Jsonata: return value from context array


#1

Hi,

I'm looking for the right jsonata expression to do the following:

I have a context variable containing a json array with the following data:
{
"Products": [
{
"ProductName": "Red Bowler Hat ",
"ProductID": 858383
},
{
"ProductName": "Green Bowler Hat",
"ProductID": 858384
}
]
}

The flow I want to create is as follows:
My inject node has a topic with the "ProductID" of the product.
Desired result: a string composed of the "ProductID" + "ProductName"

I am now trying to use a change node with a jsonata expression to search the "ProductName" in the context array, with the "ProductID" from the topic as an argument.

So for start I use this basic expression if I use the json object as input:
Products[ProductID=858383 ].ProductName

to use a context variable I use the following expression::
$flowContext('Products.Products[0].ProductName')

But now I want to replace the fixed array index between the square brackets [0] by the ProductID from the topic of the message.
Something like this:
$flowContext('Products.Products[ProductID=topic].ProductName')

This last expression is unfortunately not working. I tried a few things but until now with no succes.
Does anyone have suggestions?

thanks a lot
Pascal

my node-red flow:
[{"id":"bfe7a70c.dbcfc8","type":"change","z":"4c075864.0ddb58","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$flowContext('Products.Products[0].ProductName')\t\t","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":700,"y":440,"wires":[["6a972a5b.cdfd04"]]},{"id":"f2047df2.0117a","type":"inject","z":"4c075864.0ddb58","name":"","topic":"858383","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":410,"y":440,"wires":[["bfe7a70c.dbcfc8"]]},{"id":"6a972a5b.cdfd04","type":"debug","z":"4c075864.0ddb58","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":930,"y":440,"wires":[]},{"id":"6997b923.a9e778","type":"change","z":"4c075864.0ddb58","name":"","rules":[{"t":"set","p":"Products","pt":"flow","to":"{"Products":[{"ProductName":"Red Bowler Hat","ProductID":858383},{"ProductName":"Green Bowler Hat","ProductID":858384}]}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":710,"y":400,"wires":[[]]},{"id":"d477c511.1d3ca8","type":"inject","z":"4c075864.0ddb58","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":460,"y":400,"wires":[["6997b923.a9e778"]]}]


#2

Hi @psmtvdw

you cannot use a JSONata expression as the key passed to the flowContext function.

You would have to get the full object from context and then use a JSONata expression to pull out the piece you want:

$flowContext('Products').Products[ProductID=$$.topic].ProductName

This assumes the product ID you want to lookup is in msg.topic and that it is a number type - not a String. JSONata is strict about types.

For future reference, please read this post about sharing code/flows in the forum: How to share code or flow json


#3

Hi,

This works fine. thanks!
topic is a string by default. So I used $number() function in my jsonata expression

$flowContext('Products').Products[ProductID=$$.$number(topic)].ProductName	

the example flow:

[{"id":"bfe7a70c.dbcfc8","type":"change","z":"4c075864.0ddb58","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$flowContext('Products').Products[ProductID=$$.$number(topic)].ProductName\t","tot":"jsonata"},{"t":"set","p":"payload","pt":"msg","to":"topic & \"_\" & payload","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":760,"y":440,"wires":[["6a972a5b.cdfd04"]]},{"id":"f2047df2.0117a","type":"inject","z":"4c075864.0ddb58","name":"","topic":"858383","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":270,"y":440,"wires":[["bfe7a70c.dbcfc8"]]},{"id":"6a972a5b.cdfd04","type":"debug","z":"4c075864.0ddb58","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":1010,"y":440,"wires":[]}]