Flow.get function adds data to the flow context instead of just reading it

Hello everyone,

I have some strange behaviour with the flow.get function. This function changes the context data, although I actually only want to read it out. Is it intended to do so? Is there a way that the context data remains unchanged?

Heres some sample code:

[{"id":"b3653d879155d2f6","type":"change","z":"fd0dd2d5871eaf24","name":"flow.Test","rules":[{"t":"set","p":"Test.payload","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":920,"y":540,"wires":[["b25113f5c23eb568"]]},{"id":"b25113f5c23eb568","type":"function","z":"fd0dd2d5871eaf24","name":"","func":"// Safe clientId (incoming requests from Front-End)\nlet clientId = false;\nif (msg.hasOwnProperty('_socketId')) clientId = msg._socketId;\n\n// Clear incoming msg-Object\nmsg = {};\n\n// get Flow-Data\nmsg = flow.get(\"Test\");\nmsg.topic = \"test/currentdata\";\n\n// Attach SocketID to msg-Object\nif (clientId) msg._socketId = clientId;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1080,"y":540,"wires":[["3b8788620f01b367"]]},{"id":"c039cb90d75d2ae4","type":"inject","z":"fd0dd2d5871eaf24","name":"Front-End Data","props":[{"p":"payload.topic","v":"test/get/currentdata","vt":"str"},{"p":"_socketId","v":"RaNdOMsOCkeTiD","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":900,"y":580,"wires":[["b25113f5c23eb568"]]},{"id":"3b8788620f01b367","type":"debug","z":"fd0dd2d5871eaf24","name":"Test-Debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1250,"y":540,"wires":[]},{"id":"ac26934567734e2f","type":"inject","z":"fd0dd2d5871eaf24","name":"API-Data","props":[{"p":"payload"},{"p":"notneeded","v":"data","vt":"str"},{"p":"other","v":"data","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"actual payload","payloadType":"str","x":760,"y":540,"wires":[["b3653d879155d2f6"]]}]

Screenshot 2022-11-11 173135

Javascript passes objects by reference.
so
msg = flow.get("Test");
means that if you alter msg after you tell it is equal to flowget, both the context and msg now point to same reference.
Try
msg = RED.util.cloneMessage(flow.get("Test"));
so now msg = flowget, but it is a clone pointing to a separate reference.

2 Likes

That explains a lot. It's a pity that JavaScript only passes the memory address of objects to the variable.

I think this bites everybody at one point of another…Says a man who was bitten :joy:

It's not a pity; it's a choice. In computing there are really only two lifestyles: essentially pass-by-value or pass-by-reference. Whichever you choose, achieving the other one becomes tricky.

2 Likes

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