Skip to content

What is a message action?

In ArcGIS Experience Builder, message actions are a mechanism for communication between widgets and the framework. Widgets and the framework can both publish and listen to messages, enabling dynamic interactions and workflows. A message is identified by a MessageType, which is defined by the jimu framework. Common message types include ExtentChange and DataRecordsSelectionChange.

How to use message actions

Here are the general steps to use message actions in ArcGIS Experience Builder:

1. Declare messages and actions in manifest

To publish a message, a widget calls MessageManager.getInstance().publishMessage(message). For example, the List widget publishes the DataRecordsSelectionChange message when a list item is clicked, and the Map widget publishes the ExtentChange message when the view changes.

Each message is defined by a class. For example, ExtentChangeMessage defines the extent property as its payload.

To publish a message, declare the published messages in the manifest.json file:

Use dark colors for code blocksCopy
1
2
3
"publishMessages": [
  "DATA_RECORDS_SELECTION_CHANGE"
]

2. Publish or handle messages

If a widget needs to publish message, it should call MessageManager.getInstance().publishMessage(message). If a widget needs to handle message, it should implement the actions.

To create a message action, extend the AbstractMessageAction class. Several methods help you develop message actions:

  • filterMessageDescription: Filters available actions in the builder.

    Use dark colors for code blocksCopy
    1
    2
    3
    4
    5
    export default class QueryAction extends AbstractMessageAction {
      filterMessageDescription(messageDescription: MessageDescription): boolean {
        return [MessageType.StringSelectionChange, MessageType.DataRecordsSelectionChange].indexOf(messageDescription.messageType) > -1;
      }
    }
  • filterMessage: Filters messages when the action receive messages in runtime.

    Use dark colors for code blocksCopy
    1
    2
    3
    filterMessage(message: Message): boolean {
      return true;
    }
  • Setting UI: Some actions need a settings UI. Declare settingUri in manifest.json. To skip the settings UI in specific cases, override getSettingComponentUri and return null.

  • Action setting UI component: This is a React component with injected props. When the user changes the config, call this.props.onSettingChange to save the config, which will be available in onExecute.

    Use dark colors for code blocksCopy
    1
    2
    3
    4
    this.props.onSettingChange({
      actionId: this.props.actionId,
      config: {} // the action config
    })
  • onExecute: Handles the logic for your message type. For example, dispatching a Redux action to update state:

    Use dark colors for code blocksCopy
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    onExecute(message: Message, actionConfig?: any): Promise<boolean> | boolean {
      let q = `${(actionConfig as ConfigForStringChangeMessage).fieldName} = '${message}'`
      switch(message.type) {
        case MessageType.StringSelectionChange:
          q = `${(actionConfig as ConfigForStringChangeMessage).fieldName} = '${(message as StringSelectionChangeMessage).str}'`
          break;
        case MessageType.DataRecordsSelectionChange:
          q = `${actionConfig.fieldName} = ` +
            `'${(message as DataRecordsSelectionChangeMessage).records[0].getFieldValue(actionConfig.fieldName)}'`
          break;
      }
      getAppStore().dispatch(appActions.widgetStatePropChange(this.widgetId, 'queryString', q));
      return true;
    }

Only plain JSON objects can be stored in the Redux store. For complex objects, use MutableStoreManager:

Use dark colors for code blocksCopy
1
MutableStoreManager.getInstance().updateStateValue(this.widgetId, 'theKey', theComplexObject)

Access the object in your widget:

Use dark colors for code blocksCopy
1
this.props.mutableStateProps.theKey

Declare message actions in manifest.json:

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
"messageActions": [
  {
    "name": "query",
    "label": "Query",
    "uri": "actions/query-action",
    "settingUri": "actions/query-action-setting"
  }
]

Configure i18n support

Internationalization (i18n) for message actions follows the same pattern as for widgets, with one key difference: message actions have a "Select an action" panel. You need a default.ts file in the runtime/translations folder with property names for your actions. The label property must use the naming convention _action_<actionName>_label.

Use dark colors for code blocksCopy
1
2
3
4
export default {
  _widgetLabel: 'Message subscriber',
  _action_query_label: 'Query'
}

Code example

Create a message action in a widget

This example shows how to use message actions in a widget.

Create a class to extend the AbstractMessageAction class.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
export default class QueryAction extends AbstractMessageAction{
  filterMessageDescription(messageDescription: MessageDescription): boolean{
    return [MessageType.StringSelectionChange, MessageType.DataRecordsSelectionChange].indexOf(messageDescription.messageType) > -1;
  }

  filterMessage(message: Message): boolean{return true; }

  getSettingComponentUri(messageType: MessageType, messageWidgetId?: string): string {
    return 'actions/query-action-setting';
  }

  onExecute(message: Message, actionConfig?: any): Promise<boolean> | boolean{
    let q = `${actionConfig.fieldName} = '${message}'`
    switch(message.type){
      case MessageType.StringSelectionChange:
        q = `${actionConfig.fieldName} = '${(message as StringSelectionChangeMessage).str}'`
        break;
      case MessageType.DataRecordsSelectionChange:
        q = `${actionConfig.fieldName} = ` +
          `'${(message as DataRecordsSelectionChangeMessage).records[0].getFieldValue(actionConfig.fieldName)}'`
        break;
    }

    getAppStore().dispatch(appActions.widgetStatePropChange(this.widgetId, 'queryString', q));
    return true;
  }
}

Create a class extending React.PureComponent<ActionSettingProps>. The configuration of the message action can be changed through the onSettingChange method.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
this.props.onSettingChange({
actionId: this.props.actionId,
config: this.props.config.set('fieldName', field['name']).set('useDataSource',{
  dataSourceId: this.props.config.useDataSource.dataSourceId,
  mainDataSourceId: this.props.config.useDataSource.mainDataSourceId,
  dataViewId: this.props.config.useDataSource.dataViewId,
  rootDataSourceId: this.props.config.useDataSource.rootDataSourceId,
  fields: allSelectedFields.map(f => f.jimuName)
})
});

In the manifest.json there is a messageActions property that provides the location and information for the message action extension.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
"messageActions": [
  {
    "name": "query",
    "label": "Query",
    "uri": "actions/query-action",
    "settingUri": "actions/query-action-setting"
  }
]

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.