Lowdefy
v3.23.3/Actions/JsAction/

JsAction

SECURITY WARNING: The JsAction executes JavaScript inside your Lowdefy app. Insecure code can expose your app or data. Since Lowdefy doesn't validate your JavaScript, make sure that you only load trusted code.
(params: {
  name: string,
  args?: any[]
}): void

The JsAction action is used to call a custom JavaScript function which was loaded onto the page using the window.lowdefy.registerJsAction() method. This JavaScript function can be asynchronous. See Custom Code for more details on how to register a new JavaScript action.

The returned result of the JavaScript function is accessible through the _actions operator for subsequent actions in the event action list.

JsAction function parameters

A JsAction function is called with a context object which includes all context data objects as well as the list of args passed to the action.

(context: {
  actions: object,
  contextId: string,
  global: object,
  input: object,
  pageId: string,
  requests: object,
  state: object,
  urlQuery: object,
  user: object,
},
...args?: any[]): any

Using Lowdefy actions in a JsAction

The context passed to the custom JsAction function contains an object called actions. This object contains all the Lowdefy action functions like SetState, Request, and CallMethod. The functions can be called using the same parameters as when they are used directly in the Lowdefy configuration. Operators in these parameters are not evaluated.

Parameters

object
  • name: string: Required - The registered name of the JavaScript function to call when the action is triggered.
  • args: any[]: The array of positional arguments with which the JavaScript function should be called.

Examples

Set a Intercom user when a page is initialized:
# lowdefy.yaml
name: intercom-example
lowdefy: '3.23.3'
app:
  html:
    appendBody: |
      <script>
        function setIntercomUser(context) {
          window.intercomSettings = {
            app_id: "{{ your_intercom_app_id }}",
            name: context.user.name,
            email: context.user.email,
          };
        }
        window.lowdefy.registerJsAction('setIntercomUser', setIntercomUser);
      </script>
      <script>
        (function(){var w=window;var ic=w.Intercom;if(typeof ic==="function"){ic('reattach_activator');
        ic('update',w.intercomSettings);}else{var d=document;var i=function(){i.c(arguments);};i.q=[];
        i.c=function(args){i.q.push(args);};w.Intercom=i;var l=function(){var s=d.createElement('script');
        s.type='text/javascript';s.async=true;s.src='https://widget.intercom.io/widget/{{ your_intercom_app_id }}';
        var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);};
        if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})();
      </script>
pages:
  - id: home
    type: PageHeaderMenu
    events:
      onInitAsync:
        - id: set_intercom_user
          type: JsAction
          params:
            name: setIntercomUser
    blocks:
      # ...
Highlight search term returned by MongoDB Search Highlight:

Add a JavaScript file to highlight the search text by wapping the highlighted text with <span style="background: yellow;">{{ value }}</span>:

// file: /public/highlightText.js
  function highlightText(context, data) {
    return data.map((item) => {
      item.highlights.forEach((light) => {
        const paths = light.path.split('.');
        const key = paths[paths.length - 1];
        paths.pop();
        let res = item;
        paths.forEach((key) => {
          res = res[key];
        });
        res[key] = light.texts.reduce((acc, obj) => {
          if (obj.type === 'hit') {
            return acc.concat('<span style="background: yellow;">', obj.value, '</span>');
          }
          return acc.concat(obj.value);
        }, '');
      });
      return item;
    });
  }
  export default highlightText;

Import custom JavaScript modules:

// file: /public/modules.js
import highlightText from './highlightText.js';
window.lowdefy.registerJsAction('highlightText', highlightText);

Lowdefy setup:

# file: lowdefy.yaml
name: text-highlight-example
lowdefy: '3.23.3'
app:
  html:
    # Load the custom modules into the index.html head tag.
    appendHead: |
      <script type="module" src="/public/modules.js"></script>
connections:
  - id: products
    type: MongoDBCollection
    properties:
      collection: products
      databaseUri:
        _secret: MDB_URI
pages:
  - id: home
    type: PageHeaderMenu
    requests:
      - id: search_products
        type: MongoDBAggregation
        connectionId: products
        properties:
          pipeline:
            _array.concat:
              - - $search:
                    compound:
                      should:
                        - text:
                            query:
                              _string.concat:
                                - '*'
                                - _state: search.input
                                - '*'
                            path:
                              - title
                              - description
                        - wildcard:
                            query:
                              _string.concat:
                                - '*'
                                - _state: search.input
                                - '*'
                            path:
                              - title
                              - description
                            allowAnalyzedField: true
                    highlight:
                      path:
                        - title
                        - description
                - $addFields:
                    score:
                      $meta: searchScore
                    highlights:
                      $meta: searchHighlights
    blocks:
      - id: search.input
        type: TextInput
        properties:
          title: Type to search products
          prefix: SearchOutlined
        events:
          onChange:
            - id: get_search # get search_products query for search.input
              type: Request
              params: search_products
            - id: apply_highlight # apply the highlight transformation to the request data.
              type: JsAction
              params:
                name: highlightText
                args:
                  - _request: search_products
            - id: set_state # set the response of the apply_highlight action to state
              type: SetState
              params:
                found_products:
                  _actions: apply_highlight.response
      - id: product_results
        type: Html
        properties:
          html:
            _nunjucks:
              template: |
                <ul>
                  {% for item in found_products %}
                    <li>{{ item.title | safe }} - {{ item.description | safe}}</li>
                  {% endfor %}
                </ul>
              on:
                found_products:
                  _state: found_products

NOTE: For this example to work, you will need a products collection in your MongoDB database, populated with {title: '...', description: '...'} data objects including the following search index on the products collection:

{
  "mappings": {
    "dynamic": true,
    "fields": {
      "title": {
        "type": "string"
      },
      "description": {
        "type": "string"
      }
    }
  }
}
Use Lowdefy SetState action:
// file: /public/theAnswer.js
function theAnswer({actions}) {
  // Think for a while...
  return actions.SetState({ answer: 42 })
}
export default theAnswer;
Use Lowdefy Request action to loop over a list of requests:
// file: /public/loopRequests.js
function loopRequests({ actions }, ...requestIds) {
  return Promise.all(requestIds.map((id) => actions.Request(id)));
}
export default loopRequests;
id: call_all_requests
type: Button
events:
  onClick:
    - id: loop_requests
      type: JsAction
      params:
        name: loopRequests
        args:
          - request_1
          - request_2
          - request_3