Skip to content
Paul Williams edited this page Jun 3, 2019 · 9 revisions

A list of some useful Node-RED flavoured JSONata recipes

NOTE 2018-08-13: Since this doesn't fit nicely in the cookbook, I've transferred the information to my blog, there are some updated examples there as well.

General

Global and Flow context variables

( {
  "aGlobalVariable": $globalContext('globalVariableName'),
  "aFlowVariable": $flowContext('flowVariableName')
} )

Extract specific element from a context variable

This shows how to extract an element from a context variable based on the msg.topic and assuming you have a variable that is keyed on topic. An example might be a global variable keyed on sensor ID that contains sensor locations where you want to add the location to the data from the sensor to pass on to MQTT.

{
   "location": $globalContext('locations["' & topic & '"]'),
   "origPayload": payload
}

Accessing msg

Object entities are exposed directly as names, e.g. msg.payload is accessed simply as "payload". If you want to access the whole msg object, you need to use the "$" variable at the top level of your expression. e.g.

$._msgid

would return the unique message id. If you end up using functions or other enclosures, you can use $$ to access the top level object.

Complex example

Extracts the keys and values from the original msg, copies the original msg.payload, adds some extra object data and a timestamp. Illustrates the use of functions and variables.

(
    $lookupVals := function($i) { $lookup($$, $i) };
    $origMsgVals := $map($keys($$), $lookupVals);
    { 
      "meta": { "a": 1, "thisIs":"more data" },
      "origPayload": payload,
      "origMsgKeys": $keys($$),
      "origMsgVals": $origMsgVals,
      "timestamp": $now()
    }
)

Change Node Recipes

Add extra levels to the start of a topic

Use Set against msg.topic and use the following JSONata expression:

"EXTRA/LEVELS/" & topic

Recreate the msg on the msg.payload

Sometimes you might want to move the content of the msg to msg.payload. For example, if you wanted to send the msg as a debug to MQTT. You cannot do this directly (setting msg.payload to $) as the system thinks this is a circular reference and blocks it. So you have to recreate the msg manually. I include a list of the msg's keys so that you can know if you missed anything.

{
  "topic": topic,
  "payload": payload,
  "_msgid": _msgid,
  "msgKeys": $keys($),
}

There are undoubtedly other ways to do this in a more automated way.

Taking this slightly further, you can also get the keys and values of the original msg in an array:

(
    $spread($)
)

Reprocess a payload containing an array

How to process an array/object combination plus calculate a true/false flag from 2 properties in the array.

Example input msg:

{
    "payload": [
        {
            "Station ID": "3015432",
            "Station Name": "Sg.Klang di Tmn Sri Muda 1",
            "District": "Petaling",
            "River Basin": "Sg.Klang",
            "Last Update": "30/12/2017 01:30",
            "River Level (m)": "1.13",
            "Normal": "2.80",
            "Alert": "4.40",
            "Warning": "4.58",
            "Danger": "5.00"
        },
        {
            "Station ID": "3015490",
            "Station Name": "Sg.Damansara di TTDI Jaya",
            "District": "Petaling",
            "River Basin": "Sg.Klang",
            "Last Update": "30/12/2017 01:30",
            "River Level (m)": "13.35",
            "Normal": "3.50",
            "Alert": "7.30",
            "Warning": "7.80",
            "Danger": "8.30"
        }
    ]
}

Example JSONata to reformat the output

payload.(
    {
        "station": $.'Station ID',
        "name": $.'Station Name',
        "level": $.'River Level (m)',
        "alert": $number($.'River Level (m)') > $number($.Alert) ? true : false
    }
)

Produces:

[
  {
    "station": "3015432",
    "name": "Sg.Klang di Tmn Sri Muda 1",
    "level": "1.13",
    "alert": false
  },
  {
    "station": "3015490",
    "name": "Sg.Damansara di TTDI Jaya",
    "level": "13.35",
    "alert": true
  }
]

See https://groups.google.com/forum/#!topic/node-red/J0020rPetAY for more information.

Comments/Feedback:

  • This doesn't follow the style guide for cookbook recipes, but @knolleary suggests there's a place for a guide on jsonata in the main user guide somewhere. Keeping this until we find a place for it. - @mblackstock