Reference env variable in property name

Hi everyone, I am trying to generalize a subflow so that I can use it in multiple rooms of my place.

Some of my global scope properties look something like global.currentscene.livingroom or global.currentscene.bedroom.

What I am now doing is that I am setting an env variable $room in my subflow in the attempt to be able to set global properties dynamically from inside the subflow. In other words, I am trying to then do something like:

Change Node -> Property -> global.currentscene.$room -> Assign value

I have read the docs but it is still unclear to me whether I can achieve something like this. This page mentions not being able to reference partial stuff, but does that mean that I should instead assign a value such as global.currentscene.livingroom to my env, rather than livingroom, and then just use $room ?

Thanks

You could set the env var to a message then reference that var.
e.g.

[{"id":"62b0db36.5664cc","type":"subflow","name":"Subflow 1","info":"","category":"","in":[{"x":160,"y":120,"wires":[{"id":"18db26f9.bc2c09"}]}],"out":[{"x":440,"y":140,"wires":[{"id":"18db26f9.bc2c09","port":0}]}],"env":[{"name":"room","type":"str","value":"","ui":{"type":"input","opts":{"types":["str"]}}}],"meta":{},"color":"#DDAA99"},{"id":"18db26f9.bc2c09","type":"change","z":"62b0db36.5664cc","name":"","rules":[{"t":"set","p":"global_name","pt":"msg","to":"room","tot":"env"},{"t":"set","p":"test[msg.global_name]","pt":"global","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":240,"y":180,"wires":[[]]},{"id":"13c60667.bee79a","type":"inject","z":"bf9e1e33.030598","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":150,"y":1880,"wires":[["1e3ddcce.248b13"]]},{"id":"1e3ddcce.248b13","type":"subflow:62b0db36.5664cc","z":"bf9e1e33.030598","name":"","env":[{"name":"room","value":"tester","type":"str"}],"x":340,"y":1880,"wires":[[]]}]

When I try and import your code I get the error Error: TypeError: o is undefined

Not sure what happened there, as imports fine for me. Its a simple flow.

The sub flow just contains a change node.

[{"id":"18db26f9.bc2c09","type":"change","z":"62b0db36.5664cc","name":"","rules":[{"t":"set","p":"global_name","pt":"msg","to":"room","tot":"env"},{"t":"set","p":"test[msg.global_name]","pt":"global","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":240,"y":180,"wires":[[]]}]

The subflow enviroment variable is set like this


The injected payload is saved to global.test.[$room]

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

Reopened at request of OP

@E1cid thanks for the help and sorry about the late reply, hadn't had time to look into it.

I am bumping on an issue here:

my globals are names global.currentscene.ROOMNAME and this allows me to neatly group things together in debug because of the dot notation.

what you suggest to do is to do something like global.currentscene.[msg.room_name] but it seems like this is not allowed by NR because of the dot. I can, in fact, do global.currentscene_[msg.room_name] and NR stops complaining.

I am wndering if there is any smart way for me to keep the dot notation, though it's obviously not the end of the world and I can accept losing it.

Is valid in a change node, from node-red 1.3 i believe. I use it with no issues.
this works and creates a global

[{"id":"9700255f.3906c","type":"inject","z":"30af2d3e.d94ea2","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":250,"y":3500,"wires":[["18db26f9.bc2c09"]]},{"id":"18db26f9.bc2c09","type":"change","z":"30af2d3e.d94ea2","name":"","rules":[{"t":"set","p":"global_name","pt":"msg","to":"room","tot":"str"},{"t":"set","p":"test.test[msg.global_name]","pt":"global","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":430,"y":3500,"wires":[[]]}]

I'm on 3.0.0

image

image

You would not have the dot before the bracket, the bracket replaces the dot
e.g. test.test.test would be test.test[msg.payload]

1 Like

Oh wow, I didn't get that at all, that seems fairly unexpected, but maybe it's documented somewhere? I would not expect the content of a message to also include dot notation. I will try that out, thank you

I can confirm that this worked! I still find it weird that if msg.payload is my_string, then test[msg.payload] would translate to test.my_string rather than testmy_string.

I guess is that by intuition [msg.payload] is just a placeholder for the string value (and this might be my wrong assumption), so I would totally expect test.[msg.payload] to be accepted and translate to test.my_string

Thanks again for the help

Dot and bracket notation are fundamentals of javascript. See Working with objects - JavaScript | MDN

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