M.App Enterprise Tutorials

Not sure on how to get started or looking for a workflow to get M.App Enterprise up and running. Tutorials provide step by instruction on some of the most common configurations and workflows to get M.App Enterprise configured up and running quickly.
Showing results for 
Search instead for 
Do you mean 

Javascript API in Desktop M.App

by ‎05-08-2018 05:21 AM - edited ‎06-19-2019 12:22 PM (3,338 Views)

This tutorial describes you how to use the Javascript API in order to make Workflows communicate with the map within the Desktop application and manage medias in your workflows.

To get a comprehensive description of the whole Javascript API available in Workflows visit this page. The library described is still relevant to Workflows in M.App Enterprise. The main functions that have changed are the subject of this tutorial.


Typical workflow configuration

Using workflows you often need to fit selected objects on the map. Here is a typical configuration in a list controller, where you would like to add a button to zoom to the geometry of the corresponding row (the action will be visible only if the current row has a geometry, this is specified in the visibility property).

In this example we use a custom function called zoomTo that will be defined in a custom script (the script will be bound to the list configuration using the "script" property).


Workflow editor:



Corresponding XML definition:

<FormAction name="ZoomTo" editable="true" 
 visible="list[SQL[select count(geometry_spa) from buildingextension where gid={ROW.gid}]]"
 action="SCRIPT[zoomTo('buildingextension',{ROW.gid})]" type="row" />

We call the function passing the name ('buildingextension') we configured in Studio for this vector data and the primary key of the selected objects (placeholder {ROW.gid} will be replaced at runtime with primary key value of the current row).


Custom script:


function zoomTo(layername,featureids){
      return SC.Map.clearSelectedElements().then(function(){
          return SC.Map.setSelectedElements(featureids).then(function(){
              return SC.Map.fitSelectedElements().then(function(){
		  SC.Map.closeWebBrowser(); // since v2018 this method no longer returns a promise 
		  //return SC.Map.closeWebBrowser();
  }).fail(function (error) {



In the custom script we use several methods of the JS API to

  1. set the layer active in the legend (in case it was not active already)
  2. clear any already selected object 
  3. set the passed object selected
  4. fit the object
  5. close the web browser (this is optional)

All of these methods are asynchronous, so we have to wait for the execution before issuing the following one.


Methods provided by JS API 


The Javascript API offers methods to communicate with Desktop application in both directions. The API is asynchronous, all of the methods (unless specifically stated) return a Deferred’s Promise object, so you must always await for their execution to get the results, even for simply getting the map scale like in the following sample:



	function(results) {
			IG.notify('Current scale: ' + results).show()



Communication with the map

The first set of methods allows communication with the map. Functions can be called as SC.Map.functionName.
Here is the list of available functions:


  • setActiveLayer(layer)
    • set the layer layer active in legend
    • layer, type string: must match name provided in Studio->Content->Vector Data->"Name"
    • throws exception if layer cannot be found or is null
  • getActiveLayer()
    • returns the active layer or NULL if no layer is active
  • clearActiveLayer()
    • clears current active layer in the legend
  • getVisibleLayers()
    • returns an array of all visible layers
  • reloadLayers(layers)
    • reloads sets of layers
    • layers, type string/array of strings: single layer or Javascript array of layers to reload
  • setLayersVisible(layers)
    • sets layers visible
    • layers, type string/array of strings: single layer or Javascript array of layers to be shown
  • setLayersInvisible(layers)
    • sets layers invisible
    • layers, type string/array of strings: single layer or Javascript array of layers to be hidden
  • setLayerTranslucency(layers, translucency)
    • sets translucency of the given layers
    • layers, type string/array of strings: single layer or Javascript array of layers 
    • translucency, type number: translucency level between 0 and 1 to be set
  • setSelectedElements(selection)
    • sets the selection on the map
    • selection, type number/array of numbers: single element id or Javascript array of element id's to select
  • getSelectedElements()
    • returns Javascript array of element id's
  • fitSelectedElements()
    • fits the view on the selected elements on the map
  • clearSelectedElements()
    • clears the current map selection
  • setMapScale(mapScale)
    • sets the new map scale
    • mapScale, type number
  • getMapScale()
    • returns the current map scale
  • setMapCenter(centerX,centerY)
    • sets map center to centerX, centerY 
    • centerX, type number: horizontal value of the map center
    • centerY, type number: vertical value of the map center
  • getMapCenter()
    • returns current centerXcenterY values
  • setMapCenterAndScale(centerX,centerY,mapScale)
    • sets map center to centerXcenterY and scale to mapScale
    • centerX, type number: horizontal value of the map center
    • centerY, type number: vertical value of the map center
    • mapScale, type number: scale to use
  • setMapBounds(left,top,right,bottom)
    • sets the bounds on the map
    • left, type number: left (X max) coordinate
    • top, type number: top (Y max) coordinate
    • right, type number: right (X max) coordinate
    • bottom, type number: bottom (Y min) coordinate
  • getMapBounds()
    • returns the bounds of the map
  • bringToFront()
    • brings Desktop App to front
  • bringToBack()
    • brings Desktop App to back
  • closeWebBrowser()
    • closes the associated web browser instance
      • NOTE: since v.2018 this method no longer returns a promise
  • closeApp()
    • closes Desktop App
      • NOTE: since v.2018 this method no longer returns a promise

Geometry capturing

The API offers a dedicated method to digitize the geometry of an object. The function can be called as SC.digitize.


  • digitize(layerconfig, elementIds)
    • allows capturing of layer geometry for given elementIds
    • layer, type string: name of the layer (must match name provided in Studio->Content->Vector Data->"Name")
    • config, type object: configuration of commands:
      • commands, type array of strings: list of commands to make available (full list available in this post)
      • startOnLoad, type string: command to be selected by default
      • sample: {commands: ['NEWPOLYGON', 'NEWRECTANGLE'], startOnLoad: 'GE_NEWPOLYGON'}
    • elementIds, type array of numbers: list of elements to capture geometry of
      • sample: [{FORM.id}]

Sample to capture a new polygon:


SC.digitize('BuildingExtension_WGS84', {commands: ['NEWPOLYGON'], startOnLoad: 'NEWPOLYGON'})

Sample to edit an existing polygon:


SC.digitize('BuildingExtension', {commands: ['MODIFY'], startOnLoad: 'MODIFY'}, [{FORM.id}])


Management of medias

This set of methods offers handling of different kind of medias. A media can be an URL to open, file to edit or document to download. Functions can be called as SC.Media.functionName.

Here is the list of available functions:


  • browse(urltargetwidthheight)
    • opens the url in the internal browser
    • url, type string: url to open
    • target, type string: name of the window to open the url; null will always open a new window
    • width, type number: width of the browser window
    • height, type number:height of the browser window
  • browseInNativeBrowser(url)
    • opens the url in the default browser registered on the client
    • url, type string: url to open
  • showFile(fileName)
    • launches the associated application to open the file; if the specified file is a directory, the file manager of the current platform will be launched to open it
    • fileName, type string: file/directory to open
  • openFileInEditor(fileName)
    • launches the associated editor application and opens a file for editing
    • fileName, type string: file to edit
  • downloadAndSave(url)
    • downloads the content of the given url and prompts the user for a directory where to place the file on the local system
    • url, type string: url to download
  • downloadAndOpen(url)
    • downloads the content of the given url and opens the file in the assigned editor
    • url, type string: url to download
  • downloadFile(urlConnectionlocalFile)
    • opens an URLConnection  and stores the inputStream to the defined path
    • urlConnection, type URLConnection: urlConnection to connect to
    • localFile, type path: path where to store the local copy
    • throws IOException if the connection fails or the local file path is not accessible
  • getFileName(urlConnection)
    • returns the filename attribute of the provided URLConnection; the method tries to read the "Content-Disposition" header from the stream; if the flag is not available the fileName given by the URL is returned
    • urlConnection, type URLConnection: urlConnection to read the header information


on ‎11-15-2018 08:05 AM

Is there also an Java API/SDK to develop plugins for the Desktop M.App? Like there was for GMSC. It's not listed in the HGDN bitbucket.

‎06-21-2019 12:52 AM - edited ‎07-04-2019 11:17 PM

>>> SOLVED! 


I am using different triggers and javascript API's to upload an image and save it's path to a DB.


The uploading of the file works fine:

<FormFile name="dokumentation_foto" label="Bild auswählen" datatype="file" 
defaultvaluemode="onload" persisted="false" override="false" uploaddir="C:\Temp"
multiple="true" useuniquename="true" fileextension="png,jpg,gif" />


However, saving the string to the database through a SqlIterationTrigger throws me an error saying:

There is no mapping between the MApp.WorkflowsUploadedFile object type and a 
known managed native provider type.


>>> SOLVED! 

on ‎07-31-2019 08:17 PM



i am using setMapCenterAndScale(101.78951,2.8802,10000) it is aways going into the sea don't understand what is wrong here 


on ‎07-31-2019 09:38 PM



SC.Map.getSelectedElements() not returning any element id