Change node: dynamically set a property

Hello,

Is there a way to dynamically set a property in a change node?

Something like:

set flow.mode[msg.targetMode].enabled
to msg.payload

I know I can do it in javascript, but it would be better with a change node.

Thank you

Andy

This is possible with a jsonata expression ($eval) - here you can see an example:

Thanks for the quick answer.

I tried, but it not seams to work.

I try something like:
on the for or on the msg: $eval(topic) or $eval(msg.topic) to msg.payload
msg.topic containing "vip"
msg.payload containing "hello"

It results: flow.$eval(topic) = "hello"

Do you have a more basic exemple? When I read the thread, is looks more like a wish than a real feature.

Just show me what you tried (as exported flow). Also, which version of n-r do you have?

We are on 0.20.3

Here's the flow:

[{"id":"e9f00787.c7d228","type":"inject","z":"92c036c9.c74c08","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":480,"y":200,"wires":[["2d2b521.79b6fae"]]},{"id":"2d2b521.79b6fae","type":"change","z":"92c036c9.c74c08","name":"test","rules":[{"t":"set","p":"payload","pt":"msg","to":"hello","tot":"str"},{"t":"set","p":"topic","pt":"msg","to":"vip","tot":"str"},{"t":"set","p":"$eval(topic)","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":650,"y":200,"wires":[["bc8ccf09.1f9f4"]]},{"id":"bc8ccf09.1f9f4","type":"debug","z":"92c036c9.c74c08","name":"dynamically set topic","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":910,"y":200,"wires":[]}]

Thank you

I wonder if eval is really needed? Is this what you want? Note that the key targetMode in the second rule is evaluated (not literal).

p-02

That won't do, because if the mode bbb already exists, with other properties, they get erased. The jsonata expression recreate the bbb property entirely instead of just targetting a sub-property.

Here's an exemple

[{"id":"e9f00787.c7d228","type":"inject","z":"92c036c9.c74c08","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":480,"y":200,"wires":[["2d2b521.79b6fae"]]},{"id":"2d2b521.79b6fae","type":"change","z":"92c036c9.c74c08","name":"test","rules":[{"t":"set","p":"payload","pt":"msg","to":"true","tot":"bool"},{"t":"set","p":"topic","pt":"msg","to":"vip","tot":"str"},{"t":"set","p":"mode.vip.name","pt":"msg","to":"vip","tot":"str"},{"t":"set","p":"mode","pt":"msg","to":"{topic: {\"enabled\": payload}}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":650,"y":200,"wires":[["bc8ccf09.1f9f4"]]},{"id":"bc8ccf09.1f9f4","type":"debug","z":"92c036c9.c74c08","name":"dynamically set topic","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":910,"y":200,"wires":[]}]

Simplified dynamic property example:

[{"id":"b585fa52.babdb8","type":"inject","z":"c421dfeb.3e752","name":"","topic":"lala","payload":"{\"topic\": \"testtopic\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":402,"y":3350,"wires":[["aaf0b982.837278","8cc8db27.ee65e8"]]},{"id":"aaf0b982.837278","type":"change","z":"c421dfeb.3e752","name":"test","rules":[{"t":"set","p":"cfg.topicfield","pt":"msg","to":"topic","tot":"str"},{"t":"set","p":"topic","pt":"msg","to":"$eval(cfg.topicfield,payload)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":611,"y":3355,"wires":[["8cc8db27.ee65e8"]]},{"id":"8cc8db27.ee65e8","type":"debug","z":"c421dfeb.3e752","name":"dynamically set topic","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":849,"y":3237,"wires":[]}]

Indeed, fully agree.

@moebius

I don't understand your flow sample. It seems it just take the property topicfield and us it as a value to overrite the topic with it. But the point would be to take the value of topicfield and use it as a dynamic reference to a propperty, so I could set the value with another property

topic = "lala"

msg.payload[topic].label = "the new value"

should result:

msg.payload.lala.label = "the new value"

All without recreating the lala object and preserving his properties.

Well, it looks like you dont want to "dynamically set a property" as you wrote in the title of your thread...

Seems like you want to create a property dynamically.
So you can support my feature request :slight_smile:

Meanwhile, this is only possible with a function node afaik.

Yes, I do want to do both! Create & set.

I'll support it.

I got it working with JSONata $merge function but I have not tested thoroughly to be confident that it works well.

[{"id":"475c2554.e9f5bc","type":"tab","label":"Flow 3","disabled":false,"info":""},{"id":"c79fba99.989f08","type":"inject","z":"475c2554.e9f5bc","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":160,"y":260,"wires":[["8539380c.7095e8"]]},{"id":"8539380c.7095e8","type":"change","z":"475c2554.e9f5bc","name":"test","rules":[{"t":"set","p":"payload","pt":"msg","to":"true","tot":"bool"},{"t":"set","p":"topic","pt":"msg","to":"lala","tot":"str"},{"t":"set","p":"mode.lala.name","pt":"msg","to":"vip","tot":"str"},{"t":"set","p":"final","pt":"msg","to":"{\"mode\" : {topic : $merge ([ $lookup(mode, topic) ,  {\"label\": \"new value\"}])}}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":330,"y":260,"wires":[["5bbc8432.d8931c"]]},{"id":"5bbc8432.d8931c","type":"debug","z":"475c2554.e9f5bc","name":"dynamically set topic","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":590,"y":260,"wires":[]},{"id":"f81c9702.ccbf18","type":"inject","z":"475c2554.e9f5bc","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":160,"y":120,"wires":[["b52b8741.c6fa78"]]},{"id":"b52b8741.c6fa78","type":"change","z":"475c2554.e9f5bc","name":"test","rules":[{"t":"set","p":"payload","pt":"msg","to":"true","tot":"bool"},{"t":"set","p":"topic","pt":"msg","to":"lala","tot":"str"},{"t":"set","p":"mode.lala.name","pt":"msg","to":"vip","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":330,"y":120,"wires":[["8045059b.6421c8"]]},{"id":"8045059b.6421c8","type":"debug","z":"475c2554.e9f5bc","name":"dynamically set topic","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":590,"y":120,"wires":[]},{"id":"e728cba4.a57f08","type":"comment","z":"475c2554.e9f5bc","name":"Example","info":"","x":140,"y":80,"wires":[]},{"id":"340a83c9.74aa2c","type":"comment","z":"475c2554.e9f5bc","name":"Modified","info":"","x":140,"y":220,"wires":[]}]