Calling a REST service from JScript

In this post we will take a look how to consume a REST service from the Smart Office JScript code. Related blog posts that focus on M3 APIs can be found at the following links.
Calling M3 APIs in JScript
Background workers in Smart Office scripts

Setting up the REST Data Service

Let’s start with the script code. It’s necessary to import the following three assemblies to gain access to the necessary classes and interfaces.

import MForms;
import Mango.Core.Services;
import System.ComponentModel;

The first step is to get a handle to the REST data service from the DataServiceManager.

var svc : IDataService = DataServiceManager.Current.Get("REST");

The REST data service is configured with a parameter set put in a DataItemCollection, so we start by setting the service address. I’m going to use a fake online REST service for the example to demonstrate how it’s done.

var params = new DataItemCollection();
params.Add(new DataItem(RestDataService.KeyBaseAddress, "https://jsonplaceholder.typicode.com"));

The available parameters can be found in the RestDataService class, the name starting with Key. It’s necessary to set KeyBaseAddress for the REST requests. KeyUri can contain a relative URI that is combined with KeyBaseAddress. Both parameters support variable substitution using names within curly braces {}. For example:

params.Add(new DataItem(RestDataService.KeyUri, "/users/{userId}"));
params.Add(new DataItem("userId", e.Argument));

or like this. Both will will result in the same endpoint URL.

params.Add(new DataItem(RestDataService.KeyUri, "/users/" + e.Argument));

If the userId variable equals to 7 the combined parameters results in the REST URL:

https://jsonplaceholder.typicode.com/users/7

The service request and response type headers must be specified unless the default values are required. The default values are the following two lines, that can be added for clarity but also omitted.

params.Add(new DataItem(RestDataService.KeyAcceptHeader, RestDataService.ContentTypeApplicationXml));
params.Add(new DataItem(RestDataService.KeyOutputType, RestDataService.OutputTypeDataItem));

 

Use the Background Worker to Prevent UI Freeze

Now we’re almost done, but the data service require that it’s running on a background thread. If not, it will throw an Exception to make you aware of that. This is done to prevent potential UI freeze and annoyed users. Let’s have a look at a simple solution by using the BackgroundWorker class.

var worker = new BackgroundWorker();
// Set the function that performs the service call
worker.add_DoWork(OnDoWork); 

// Set the function that performs update and clean-up after the call is done        
worker.add_RunWorkerCompleted(OnRunWorkerCompleted); 

// Launch the service call and provide start parameters
worker.RunWorkerAsync(serviceParameters);

The OnDoWork function will execute on the background  thread and call the data service. When done the OnRunWorkerCompleted function will execute on the UI thread to handle the response and do clean up after the call. Please, always handle Exceptions in your code!

public function OnDoWork(sender : Object, e : DoWorkEventArgs) 
{
    try 
    {
       var serviceParameters = e.Argument;
       // The data service call is done here (this is the background thread)
       e.Result = serverResponse
    } 
    catch(ex) 
    {
       // Exceptions must be handled
    }         
}   
public function OnRunWorkerCompleted(sender : Object, e : RunWorkerCompletedEventArgs) 
{
    try 
    {
       var worker = sender;
       worker.remove_DoWork(OnDoWork);
       worker.remove_RunWorkerCompleted(OnRunWorkerCompleted);
       var serviceResponse = e.Result;
       // The worker has completed its work (this is the UI thread) 
    } 
    catch(ex) 
    {
        // Exceptions must be handled 
    } 
}

The Full Script Example

Here is the full script example for you to test in the ISO Script Tool mforms://jscript:

import MForms;
import Mango.Core.Services;
import System.ComponentModel;

package MForms.JScript 
{
   class RESTDemo 
   {
      var debug;
      var controller;     
      public function Init(element: Object, args: Object, controller : Object, debug : Object) 
      {
         this.debug = debug;
         this.controller = controller;        
         debug.WriteLine("Script Initializing.");            
         DoRestCallOnBackgroundWorker();        
      }
    
      public function DoRestCallOnBackgroundWorker()
      { 
         debug.WriteLine("The REST service call is made on a background worker");          
         var worker = new BackgroundWorker();
         worker.add_DoWork(OnDoWork);
         worker.add_RunWorkerCompleted(OnRunWorkerCompleted);
        
         var userId = 7;         
         worker.RunWorkerAsync(userId);
      }
      public function OnDoWork(sender : Object, e : DoWorkEventArgs) 
      {
         try 
         {
            debug.WriteLine("OnDoWork started");
            debug.WriteLine("Calling a REST service getting DataItem response data");

            var svc : IDataService = DataServiceManager.Current.Get("REST");
            var params = new DataItemCollection();
            params.Add(new DataItem(RestDataService.KeyBaseAddress, "https://jsonplaceholder.typicode.com/"));             
            params.Add(new DataItem(RestDataService.KeyUri, "users/{userId}"));                          
            params.Add(new DataItem(RestDataService.KeyAcceptHeader, RestDataService.ContentTypeTextXml)); // default value                                  
            params.Add(new DataItem(RestDataService.KeyOutputType, RestDataService.OutputTypeDataItem));   // default value
            params.Add(new DataItem("userId", e.Argument)); 
            
            var dataRequest = new DataRequest(params);
            dataRequest.OperationType = "GET";
            var dataResponse = svc.Execute(dataRequest.OperationType, dataRequest);
            e.Result = dataResponse.Data;            
            debug.WriteLine("OnDoWork done");    
         } 
         catch(ex) 
         {
           debug.WriteLine("Exception: " + ex.Message);
           e.Result = null;
         }         
      }
      public function OnRunWorkerCompleted(sender : Object, e : RunWorkerCompletedEventArgs) 
      {
         try 
         {
            debug.WriteLine("OnRunWorkerCompleted running on UI thread");    
            var worker = sender; 
            worker.remove_DoWork(OnDoWork);
            worker.remove_RunWorkerCompleted(OnRunWorkerCompleted);
            if(e.Error != null) 
            {
               debug.WriteLine("Error: " + e.Error.Message); 
               return;
            }
            debug.WriteLine("Fetched user data for:");           
            var dataItem = e.Result;
            debug.WriteLine(dataItem["name"] + " (" + dataItem["username"] + ")" + " Phone " + dataItem["phone"]);  
         } 
         catch(ex) 
         {
            debug.WriteLine("Exception: " + ex.Message);
         }
      }
   }
}

 

Debug output when running the sample in the Script Tool.

Script Initializing.
The REST service call is made on a background worker
OnDoWork started
Calling a REST service getting DataItem response data
OnDoWork done
OnRunWorkerCompleted running on UI thread
Fetched user data for:
Kurtis Weissnat (Elwyn.Skiles) Phone 210.067.6132

Recent enhancements to Infor Smart Office for Lawson applications

With each 10.2.1.x hotfix for Smart Office, in addition to fixes of reported issues, many enhancements have also been included.  And with each release, we update the Knowledgebase article that summarizes those changes (KB-1626878). This post will provide some more detail about the enhancements included over the second half of 2018 and those so far in 2019.

10.2.1.0.329 (HF31)

1) A new user setting (Toolbox width on the Advanced tab) allows for a wider presentation of the forms and lists toolbox area.

2) In addition to the width setting, there is now also a setting to allow the toolbox to be locked in the open or displayed position.

Toolbox

3) Alpha filter fields on lists have always defaulted to a ‘Starts with’ comparison, but a new application setting (Default alpha search type – set in the Settings Editor for S3.Client) allows an administrator to change the default to ‘Contains’.

AlphaFilter

10.2.1.0.333 (HF32)

1) On the Actions menu of standard forms, there is now a menu item to launch the list view for forms that support it.

LaunchVendorList

2) Three enhancements were made to the Script tool: a) the help menu links to the Microsoft .NET reference; b) some common .NET event handler helpers were added; and c) the search providers were added to the context menu.

 

10.2.1.0.341 (HF33)

1)  Three new methods were added to the supported scripting model (as documented in the Object Browser): IForm GetFieldByNumer and IField Get/SetAttribute.

2) Before publishing a script file to the server, it is now scanned for non-ASCII characters which might cause subsequent compilations to fail. These characters might be introduced by writing script in another editor and pasting to the Script tool.

ScriptTool

3) A search feature was added to the Personalization Manager which allows an administrator the ability to find form and list personalizations by token as well as finding references to Jscript files.

LawsonPersonalizationManager

 

10.2.1.0.351 (HF34)

1) In addition to several minor enhancements, two major personalization enhancements for standard forms were introduced: the ability to display hidden fields and the ability to move standard elements. These are both described in greater details in this post: New Personalization features for Infor Smart Office for Lawson.

10.2.1.0.353 (HF35)

1)  A search feature was added to the Object Browser for help in locating property and method documentation and sample code.

SearchObjectBrowser

10.2.1.0.359 (HF36)

Note: this hot fix has been pulled due to the introduction of a serious regression in the M3 client. Since hotfixes are cumulative, the enhancements listed here are included in hot fix 37

1)  Infor Browser calculated fields can now be used as an operand for another calculated field.

2) A Lawson System Check utility is available to administrators to examine various settings and provide recommended changes, if any.

3) Three new scripting enhancements were added: two methods added to ControlsUtil (AddCustomTextBlock and AddCustomGroupLine); and constant for setting element foreground colors to the selected theme color (ScriptConstants.ThemeBrush).

4) The net://auth protocol is intended only to support Lawson web content and since the only version of Internet Explorer now supported by Lawson is IE 11, if the user’s browser emulation is not set to IE 11 with the net application is launched, a warning will be displayed. Administrators should consider locking the browser emulation application setting in the Settings Editor.

WebBrowserEmulation

10.2.1.0.361 (HF37)

1)  Two scripting enhancement were added to the supported scripting model (as documented in the Object Browser): an IField event, FieldValueChanged and the static class, HotkeyActions, which documents hotkey action names.

2) A new Profile setting in the SmartClient section of the Profile Editor (LogonBannerUrl) allows administrators to specify the URL of custom content to display in a browser control as users logon.

LogonBannerUrl

Smart Office commands cheat sheet

Smart Office has a number of commands, or in fact they are all links that will perform an action like opening a tool or clearing a cache. A special thanks to Jarda Dedek at EYELEVEL for sending me the original list. I took it and added a few tips of my own. In Smart Office every application is launched by an Uri. The Uri consists of a schema, like http and https, but we use mforms, sforms etc to identify different applications. As it turns out the short form links: is also a valid Uri, it’s just that it has no path, just the schema.

Download PDF version

Command Description
mforms://cmp600 Company switch
mforms://cmp100200 Division switch
mforms://lngcz Language switch
mforms://mitest MI Test
mforms://_command?value=clear cache Clear language and view definition cache. (No other caches) The reply from the command will show what caches have been cleared.
mforms://_command?value=clear view Clear view
mforms://_command?value=clear view all Clear all views
mforms://_command?value=clear lngcache Clear language cache
mforms://_command/?value=clear custcache Clear customization cashes in UI Adapter
mforms://jscript Script Tool
mforms://jscript/clear Clearing jScript cache with confirmation
mforms://jscript/clear&silent Clearing jScript cache without confirmation
mforms://_automation?template=<TEMPLATE NAME>&<NAME1>=<VALUE2>&<NAMEn>=<VALUEn> Automation links crated in Automation builder
mforms://_automation/?data=<AUTOMATION XML>  Automation link with automation file uploaded to server
admin://file/category Category File Administration
admin://importexportmanager Import/Export Manger
admin://installpointmnanager Install Point Manager
admin://predefinedwidgets Predefined Widgets
admin://profileeditor Profile Editor
admin://settingseditor Settings Editor
admin://userhistory User Logon History
admin://videosmanager Videos Manager
startpad://manager StartPad Manager
admin://file/category?category=StartPad StartPad File Administration – Start pad
admin://file/category?category=Mashup StartPad File Administration – Mashup
links: Link Manager
dev:help List of development commands
dev:icons Show icons
dev:local Show local folder
dev:localscriptpath Show local script path
dev:log Shows log
dev:supportzip Creates a zip with the log file and some other files like settings
dev:roaming Shows roaming folder
dev:root Shows root folder
dev:bin Shows bin folder
dev:user Shows local folder with user profile. All U** in S0 folder then can be deleted to refresh views/starting_values/user_data.
C:\Users\jarded\AppData\Local\Apps\2.0\
dev:server Show server folder
dev:shared Shows share folder
dev:resetlang Resets language
internal://log Smart office Log viewer
internal://log?search=idledetect Add a free-text search parameter to start with all entries matching the search criteria, in this example all entries related to user idle detection.
internal://log?search=idledetect&session=2

internal://log?search=idledetect&session=last

internal://log?search=idledetect&session=prev

This can be extended with the session parameter to specify the initial session to select in the log. It can be a value [1..n], last will select the current session, prev will select the previous session and full selects the whole log file. Previous is useful if you examine something that happens during shutdown and you examine the log after a restart.
internal://log?cat=service unavailable
internal://log?cat=service%20unavailable
internal://log?cat=service unavailable&session=full
You can specify the category you defined as initial selection.

 

internal://log?search=idledetect&sessiontime=13:10 The session time parameter that may be useful in some special cases and if the session time parameter is present the session parameter is ignored.
internal://themeulator Canvas theme Emulator
tool://wstest Web services test tool
widget: Opens the widget library
widget://add/?scheme=Mango.Widgets.MenuWidget Adds a widget to the canvas, use the widget ID to specify which widget to add.

 

 

 

M3 TechEd – Reporting capabilities

I took the opportunity to leave the hands-on lab and watched Mike Fletcher’s session on Reporting capabilities within Infor M3. He started off showing Homepages, and how to use it to present operational metrics, analyzing current data from M3. The session presented a number of other techniques as well.

F4DC1C6C-3C17-4C94-9622-9FC8E14252E5

An example is to show a monitor, with the count of stopped orders, and then being able to go to the list from the Monitor Widget.

Another example was to show items under development without prices by using search. The query was built by selecting “add to search” from the context menu on the column header. The search query can then be added to a menu in Homepages so that you have a link to the tasks that you work with on a regular basis.

In business context and context applications are also a form of reporting that can provide context information to M3 data, including Birst reports, Infor Document Management documents, as well as H5 Mashup applications as Context Applications.

A great session that give business context to the development that I’ve been working on. It is always nice to see how powerful the different widgets, SDKs and H5 are from a business perspective.

I also got some good feedback from customers and partners which is really what TechEd is all about, learning from each other.

M3 TechEd – Day 2

Today is day 2 at M3 TechEd. We started with Infor OS and Heath on the main stage. Infor OS is great and will give you a lot of value. If you want to learn all about Infor OS don’t miss the coming TechEd in Las Vegas in February.

C772F287-2EB2-44A9-839C-1A6FE11CDED1

Heath started with Infor OS and a quick overview.

CE542FE8-0EE1-4B96-A396-219DB68E5E1D

Infor Document Management is a living repository for collaborating around documents.

Next on stage was Torbjörn on User Experience starting with Homepages the application that is built for role based, highly configurable widgets presenting a process based view, highlighting those items you need to take action on.

94DA5E14-864C-41D2-9475-CF5658E83FF7.jpeg

Then there was a great session on organization change management by Carol Tyler and how we at Infor is transforming the industry and cultivating our culture of innovation.

Yesterday I arrived early, in the dark, and I left, in the dark. That’s just how it is in December in Stockholm. Today I was half an hour later, just in time to catch the sunrise.

 

Beautiful sunrise facing Gröna Lund and Djurgården, on the other side.

Moving to H5 and Infor OS from Smart Office

My last session of the day was  Smart Office compared to H5 and how to move from Smart Office to H5 and Infor OS. I was assisting Magnus as a subject expert. Not that he needed my help.

B06ED645-9BBD-4AC2-98A6-84E59A9AFD75

This session will be held tomorrow as well, so if you missed it, there is another chance.

There are a few tools that will help you make the move. For example moving links and favorites. But please note that not all links will work. H5 will handle mforms:// links, but there might be some links that will not work, for example anything that is accessing the file system or other schemas than mforms and https.

The clients are of course different but the M3 UI Adapter is still the same and both client talk to the MUA server when it runs M3 programs. With H5 comes Infor Ming.le and the complete Infor OS. Below is a comparison between the featureset in H5 and Smart Office.

SmartOfficevsH5

We spent some time on Ming.le Homepages which is the product I’ve been working on lately. It is a great starting point for all types of users and with the M3 widgets you can monitor and take actions and have standard pages for different roles.

The M3 Implementation Accelerator (IA) solutions from July 2018 incorporate a small number of role-based Ming.le homepages designed to complement the preconfigured solutions. Depending on the industry, there are typically six roles containing these templates:

  • General Ledger Controller
  • Accounts Payable Controller
  • Accounts Receivable Controller
  • Customer Services
  • Production Manager
  • Purchase Manager

They are all available for download, fee, in KB 2008101.

M3 TechEd

I’m at M3 TechEd in Stockholm. If you are attending don’t miss checking out the hands-on open lab. There are a lot of experts available to help you and show you what we are working on and how we can help you be successful.

50D4E859-514E-4A66-A44B-D7676036A32B

Ole Rasmussen presenting M3 product strategy.

Great location at Elite Hotel at Nacka stand. I came in early.

 

I’ll be on two tracks, Extensibility and User Experience, see you there 😀.