How to use msg.payload string value in JSONata?

In this picture I use the word 'product' in the name:value pairs of payload.{ }
Is it possible to set the name 'product' with the string value of a msg.?

By example. The msg.test message contains a string value: 'product'.
Is it possible to use this message as the "name:value" pair?

I thought the JSONata must be like: payload.{msg.test: $}
But this doesn't work... :roll_eyes:

I tried a lot of different things but doesn't have a clue to do this. :confused:
Can anyone help me?

Please share an example of the output msg JSON you are expecting to get. And an example copy of the input msg

Hello Wolff,

I am not pretty sure, if I understood you well, but did you check the helper function setObjectProperty(msg, prop, value, createMissing) (ref. Node-RED) already? - Maybe this can help you.

If not, I would need more information to understand your problem. Maybe - as requested already - some more examples.

Cheers
Ranki

If I understand your question, it may be as simple as this: { test: payload }

Here is what it looks like in a change node, given the 2 fields test and payload as strings...

image

This works because the bare words "test" and "payload" are both replaced by their values in the msg object. So be careful to make sure the "test" string is valid for use as a field name in the newly created output object (so no spaces, newlines, and weird punctuation) -- or else the change node will fail.

As Julian suggests, giving examples of your input data (and desired output object) will go a long way to getting better help... For instance, your example expression shows payload.{...} which implies that your payload is an array. If that is the case, then the expression would have to pull the "test" value from the root of the message, so the expression would be something like payload.{ $$.test: $ }

When you use the dot . operator, each element of the array is used as the "context" of the expression inside curly braces (which is why $ evaluates to the current element). To use another field on the msg which is at the same level as payload requires the $$. prefix to start the lookup at the top of the msg structure. Hope that makes sense.

1 Like

The thing I want to do is:
I have 2 dropdown menus. When I select the product in 'dropdown product' I want to select in the 'dropdown type' the product type.
So when I select ball in 'product'. I want to select the type of ball in 'type'.

I used a template node to simulate the following csv file:
Schermafbeelding 2021-05-10 om 18.10.55

This is the flow:

[{"id":"8c0623de.87ca1","type":"inject","z":"b4370c04.a6c7d","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":240,"y":2640,"wires":[["3ce8055d.54a18a"]]},{"id":"3ce8055d.54a18a","type":"template","z":"b4370c04.a6c7d","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"product,ball,train,hat\nball,baseball,yellowtrain,bighat\ntrain ,football,bluetrain,smallhat\nhat,tennisball,redtrain,mediumhat","output":"str","x":280,"y":2680,"wires":[["a1092c24.2d9c8"]]},{"id":"a1092c24.2d9c8","type":"csv","z":"b4370c04.a6c7d","name":"","sep":",","hdrin":true,"hdrout":"none","multi":"mult","ret":"\\n","temp":"","skip":"0","strings":true,"include_empty_strings":"","include_null_values":"","x":430,"y":2680,"wires":[["710b3dda.63a9b4","36d6405f.fb078","c348b469.19c818"]]},{"id":"710b3dda.63a9b4","type":"change","z":"b4370c04.a6c7d","name":"change1","rules":[{"t":"set","p":"options","pt":"msg","to":"payload.{product: product}","tot":"jsonata"},{"t":"set","p":"test","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":2680,"wires":[["41316f23.24fc1","86da049b.8aed18"]]},{"id":"41316f23.24fc1","type":"ui_dropdown","z":"b4370c04.a6c7d","name":"","label":"product","tooltip":"","place":"Select option","group":"7da9517d.305a1","order":1,"width":0,"height":0,"passthru":false,"multiple":false,"options":[{"label":"test","value":"","type":"str"}],"payload":"","topic":"topic","topicType":"msg","x":820,"y":2680,"wires":[["3fbad61f.c17efa","8835f550.6d4fb"]]},{"id":"3fbad61f.c17efa","type":"debug","z":"b4370c04.a6c7d","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":990,"y":2640,"wires":[]},{"id":"36d6405f.fb078","type":"debug","z":"b4370c04.a6c7d","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":590,"y":2640,"wires":[]},{"id":"c348b469.19c818","type":"change","z":"b4370c04.a6c7d","name":"change2","rules":[{"t":"set","p":"options","pt":"msg","to":"payload.{$$.test: $$.test}","tot":"jsonata"},{"t":"delete","p":"payload","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":780,"y":2800,"wires":[["28949ca7.79c294","6def0228.d2382c"]]},{"id":"28949ca7.79c294","type":"ui_dropdown","z":"b4370c04.a6c7d","name":"","label":"type","tooltip":"","place":"Select option","group":"7da9517d.305a1","order":2,"width":0,"height":0,"passthru":false,"multiple":false,"options":[{"label":"","value":"","type":"str"}],"payload":"","topic":"topic","topicType":"msg","x":990,"y":2800,"wires":[[]]},{"id":"6def0228.d2382c","type":"debug","z":"b4370c04.a6c7d","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":970,"y":2760,"wires":[]},{"id":"8835f550.6d4fb","type":"change","z":"b4370c04.a6c7d","name":"","rules":[{"t":"set","p":"test","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1030,"y":2680,"wires":[["a34961c7.b9cb78","c348b469.19c818"]]},{"id":"a34961c7.b9cb78","type":"debug","z":"b4370c04.a6c7d","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1210,"y":2680,"wires":[]},{"id":"86da049b.8aed18","type":"debug","z":"b4370c04.a6c7d","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":810,"y":2640,"wires":[]},{"id":"7da9517d.305a1","type":"ui_group","name":"","tab":"1ea6ab39.e574b5","order":1,"disp":true,"width":"6","collapse":false},{"id":"1ea6ab39.e574b5","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

When I fill the following in 'change2' i get a list op ball types:
image

But I want to use msg.test to fill in the word 'ball'. So the dropdown 'type' becomes dynamic. So if I choose another product, the types of that product can be chosen
I tried with $$.test to select the string of msg.test but that doesn't work.

I don't understand what I'm doing wrong.

image
image

Can you share the payload containing the differen product types ?

What do you mean?
The different product types are in the template node:
image

Hi Wolff,

Maybe you should check out this entry in the forum (btw: I received it looking for „depending drop down“):
https://discourse.nodered.org/t/problem-with-drop-down-menu/34003

There you find an option with msg.options to send the possible options for the dropdown; meaning: as soon as one value is selected in the first drop down you can serve the possible options to the second one.

Update: just saw, that you know the msg.options already. :-/ - Do you definitely need to use the csv or does it maybe make sense to have the values in a function? Are the values updated regularly?

Cheers
Ranki

Hi Ranki,

Thanks for helping!
Yes I know the msg.options. But I don't send the whole list of options to the second dropdown. Do you tested my flow and saw that?

I need to use the csv to choose the options. Because I want to be able to update the options by updating the csv with no need to update the flow.

What do in need to send to the second dropdown?

Try $lookup()

[{"id":"965ef7ad.16d87","type":"inject","z":"9b3f9f31.c45298","name":"","props":[{"p":"payload"},{"p":"test","v":"product","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":230,"y":780,"wires":[["d16bafd0.71ee88"]]},{"id":"d16bafd0.71ee88","type":"template","z":"9b3f9f31.c45298","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"product,ball,train,hat\nball,baseball,yellowtrain,bighat\ntrain,football,bluetrain,smallhat\nhat,tennisball,redtrain,mediumhat","output":"str","x":110,"y":860,"wires":[["21a21fc0.7d62"]]},{"id":"21a21fc0.7d62","type":"csv","z":"9b3f9f31.c45298","name":"","sep":",","hdrin":true,"hdrout":"none","multi":"mult","ret":"\\n","temp":"","skip":"0","strings":true,"include_empty_strings":"","include_null_values":"","x":260,"y":860,"wires":[["a82f5588.69ba6","639a655b.e7658c"]]},{"id":"a82f5588.69ba6","type":"change","z":"9b3f9f31.c45298","name":"","rules":[{"t":"set","p":"options","pt":"msg","to":"$lookup(payload,\"product\")","tot":"jsonata"},{"t":"move","p":"payload","pt":"msg","to":"hold","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":860,"wires":[["e89f457d.42e71"]]},{"id":"639a655b.e7658c","type":"debug","z":"9b3f9f31.c45298","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":360,"y":800,"wires":[]},{"id":"e89f457d.42e71","type":"ui_dropdown","z":"9b3f9f31.c45298","name":"","label":"product","tooltip":"","place":"Select option","group":"7da9517d.305a1","order":4,"width":0,"height":0,"passthru":false,"multiple":false,"options":[{"label":"","value":"","type":"str"}],"payload":"","topic":"topic","topicType":"msg","x":650,"y":860,"wires":[["a4e8e83.9c24918","1ec6e7b6.c33a7"]]},{"id":"a4e8e83.9c24918","type":"debug","z":"9b3f9f31.c45298","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":800,"y":800,"wires":[]},{"id":"1ec6e7b6.c33a7","type":"change","z":"9b3f9f31.c45298","name":"","rules":[{"t":"set","p":"options","pt":"msg","to":"$lookup($flowContext(\"hold\"),payload)","tot":"jsonata"},{"t":"delete","p":"payload","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":480,"y":940,"wires":[["48f845ee.cd1b24"]]},{"id":"48f845ee.cd1b24","type":"ui_dropdown","z":"9b3f9f31.c45298","name":"","label":"type","tooltip":"","place":"Select option","group":"7da9517d.305a1","order":4,"width":0,"height":0,"passthru":false,"multiple":false,"options":[{"label":"","value":"","type":"str"}],"payload":"","topic":"topic","topicType":"msg","x":680,"y":940,"wires":[["e9824a3.3b60238"]]},{"id":"e9824a3.3b60238","type":"debug","z":"9b3f9f31.c45298","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":830,"y":940,"wires":[]},{"id":"7da9517d.305a1","type":"ui_group","name":"","tab":"1ea6ab39.e574b5","order":1,"disp":true,"width":"6","collapse":false},{"id":"1ea6ab39.e574b5","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

Thank you very much @E1cid !
It works like magic. Trying to understand it...

[{"product":"ball","ball":"baseball","train":"yellowtrain","hat":"bighat"},{"product":"train","ball":"football","train":"bluetrain","hat":"smallhat"},{"product":"hat","ball":"tennisball","train":"redtrain","hat":"mediumhat"}]

$lookup(array_of _object, key_search_value) will go through each object of the array and find the value of any property with the matching key. It returns an array of values found.

@MrWolff : I have taken the following input for the jsonata expression.

{
  "test": "ball",
  "payload": [
    {
      "product": "ball",
      "ball": "baseball",
      "train": "yellowtrain",
      "hat": "bighat"
    },
    {
      "product": "train",
      "ball": "football",
      "train": "bluetrain",
      "hat": "smallhat"
    },
    {
      "product": "hat",
      "ball": "tennisball",
      "train": "redtrain",
      "hat": "mediumhat"
    }
  ]
}

For the above input the below jsonata expression will do the job:

$lookup(payload,test)

I have tested it - see following link

For documentation about $lookup() function see:

If the input is in a different format - please share the actual input.

Thank you very much @janvda !
That was a good explanation.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.