Bug updating global arrays

I've been hitting my head against a certain code behavior which I believe`I've captured in the following flow.
I'm trying to do something quite simple.
I have two global arrays (flow arrays): current_array and last_array
I want to be able to update the current_array one element at a time, and at certain times, I would like to copy the current_array to the last_array.

This works fine when I update the entire array like this:

flow.set("current_array", [1,2,3,4,5,6]);

but it fails (sometimes) when I update it like this:

var current_array = flow.get("current_array");
current_array[0] = 500;
flow.set("current_array", current_array);

It only fails after I have copied a current_array to the last_array. Almost always immediately after I have done so. It's as if, updating the current_array also updates last_array, or that by updating current_array, it triggers the function containing the "set last_array to current_array". If I comment out the "set last_array to current_array", it doesn't happen, but also the code stops working. I don't understand why the "set last_array to current_array" triggers without input, only when I update a global variable, sometimes.

I am happy to explain the order of operations in order to make the bug happen, if it is unclear.

Any help is greatly appreciated.

[{"id":"28f94018.02097","type":"inject","z":"6fb2422e.195b2c","name":"initialize arrays on deploy","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":350,"y":80,"wires":[["fb35bd2c.7dd53"]]},{"id":"fb35bd2c.7dd53","type":"function","z":"6fb2422e.195b2c","name":"initialize flow variables","func":"flow.set(\"current_array\", [0,0,0,0,0,0,]);\nflow.set(\"last_array\", [0,0,0,0,0,0])\nmsg.payload = \"initialized arrays\";\nreturn msg;","outputs":1,"noerr":0,"x":620,"y":80,"wires":[["2185412.babbfbe"]]},{"id":"2185412.babbfbe","type":"debug","z":"6fb2422e.195b2c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":850,"y":80,"wires":[]},{"id":"8d236d30.a31a3","type":"inject","z":"6fb2422e.195b2c","name":"print current array","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":320,"y":160,"wires":[["14cffb62.b44875"]]},{"id":"14cffb62.b44875","type":"function","z":"6fb2422e.195b2c","name":"initialize flow variables","func":"msg.payload = \"current array: \" + flow.get(\"current_array\");\nreturn msg;","outputs":1,"noerr":0,"x":620,"y":160,"wires":[["4ece0999.058cd8"]]},{"id":"4ece0999.058cd8","type":"debug","z":"6fb2422e.195b2c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":850,"y":160,"wires":[]},{"id":"8d3b8f58.179af","type":"inject","z":"6fb2422e.195b2c","name":"print last array","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":309.00001525878906,"y":202.00000381469727,"wires":[["e55814ef.b83e48"]]},{"id":"e55814ef.b83e48","type":"function","z":"6fb2422e.195b2c","name":"initialize flow variables","func":"msg.payload = \"last array: \" + flow.get(\"last_array\");\nreturn msg;","outputs":1,"noerr":0,"x":619.0000152587891,"y":202.00000381469727,"wires":[["c35d6fc7.c0cae"]]},{"id":"c35d6fc7.c0cae","type":"debug","z":"6fb2422e.195b2c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":849.0000152587891,"y":202.00000381469727,"wires":[]},{"id":"d6183394.aec2f","type":"inject","z":"6fb2422e.195b2c","name":"set last array to current array","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":360.00001525878906,"y":720.0000076293945,"wires":[["234ef22a.b130be"]]},{"id":"234ef22a.b130be","type":"function","z":"6fb2422e.195b2c","name":"set last_array to current_array","func":"var current_array = flow.get(\"current_array\");\nflow.set(\"last_array\", current_array);\nmsg.payload = \"set last array to current array\";\nreturn msg;","outputs":1,"noerr":0,"x":630.0000152587891,"y":720.0000076293945,"wires":[["9990ef93.d4e31"]]},{"id":"9990ef93.d4e31","type":"debug","z":"6fb2422e.195b2c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":869.0000152587891,"y":720.0000114440918,"wires":[]},{"id":"b64a4983.51a9a8","type":"inject","z":"6fb2422e.195b2c","name":"load preset 1","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":450,"y":320,"wires":[["8bf9b031.9fcdd"]]},{"id":"ff41b1cb.1daa9","type":"inject","z":"6fb2422e.195b2c","name":"load preset 2","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":449.00001525878906,"y":361.0000057220459,"wires":[["87cfdf89.43fc7"]]},{"id":"7f760e6b.b2b4c","type":"inject","z":"6fb2422e.195b2c","name":"load preset 3","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":449.00001525878906,"y":400.0000057220459,"wires":[["a2bdc348.2f047"]]},{"id":"8bf9b031.9fcdd","type":"function","z":"6fb2422e.195b2c","name":"setting current array","func":"flow.set(\"current_array\", [1,2,3,4,5,6]);\nmsg.payload = \"setting current array to preset 1: \" + flow.get(\"current_array\");\nreturn msg;","outputs":1,"noerr":0,"x":700,"y":320,"wires":[[]]},{"id":"87cfdf89.43fc7","type":"function","z":"6fb2422e.195b2c","name":"setting current array","func":"flow.set(\"current_array\", [7,7,7,7,7,7,7]);\nmsg.payload = \"setting current array to preset 2: \" + flow.get(\"current_array\");\nreturn msg;","outputs":1,"noerr":0,"x":699.0000152587891,"y":361.0000057220459,"wires":[[]]},{"id":"a2bdc348.2f047","type":"function","z":"6fb2422e.195b2c","name":"setting current array","func":"flow.set(\"current_array\", [8,7,6,5,4,3]);\nmsg.payload = \"setting current array to preset 3: \" + flow.get(\"current_array\");\nreturn msg;","outputs":1,"noerr":0,"x":699.0000152587891,"y":400.0000057220459,"wires":[[]]},{"id":"b1e3cb41.30f1b8","type":"inject","z":"6fb2422e.195b2c","name":"update 1 part of array","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":482.00001525878906,"y":483.00000953674316,"wires":[["6f554c71.7c2224"]]},{"id":"9dc50cbe.e2cc5","type":"inject","z":"6fb2422e.195b2c","name":"update 1 part of array","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":482.00000762939453,"y":524.0000076293945,"wires":[["2f310b17.a747b4"]]},{"id":"d99fafa4.6e51f","type":"inject","z":"6fb2422e.195b2c","name":"update 1 part of array","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":484.00001525878906,"y":566.0000085830688,"wires":[["e6dca23a.5e329"]]},{"id":"6f554c71.7c2224","type":"function","z":"6fb2422e.195b2c","name":"setting current array","func":"var current_array = flow.get(\"current_array\");\ncurrent_array[0] = 500;\nflow.set(\"current_array\", current_array);\nmsg.payload = \"setting current array to preset 1: \" + flow.get(\"current_array\");\nreturn msg;","outputs":1,"noerr":0,"x":702.0000152587891,"y":483.00000953674316,"wires":[[]]},{"id":"2f310b17.a747b4","type":"function","z":"6fb2422e.195b2c","name":"setting current array","func":"var current_array = flow.get(\"current_array\");\ncurrent_array[2] = 200;\nflow.set(\"current_array\", current_array);\nmsg.payload = \"setting current array to preset 1: \" + flow.get(\"current_array\");\nreturn msg;","outputs":1,"noerr":0,"x":702.0000076293945,"y":524.0000076293945,"wires":[[]]},{"id":"e6dca23a.5e329","type":"function","z":"6fb2422e.195b2c","name":"setting current array","func":"var current_array = flow.get(\"current_array\");\ncurrent_array[5] = 1000;\nflow.set(\"current_array\", current_array);\nmsg.payload = \"setting current array to preset 1: \" + flow.get(\"current_array\");\nreturn msg;","outputs":1,"noerr":0,"x":704.0000152587891,"y":566.0000085830688,"wires":[[]]}]

Kristin,

if you edit your post and put 3 backticks ``` before and after your code it will get formatted correctly.

1 Like

HI, indeed, this unwanted behavior will happen when you try to copy an array to another array using the assignment operator (or using the flow.set like you did). In JavaScript assigning current_array to last_array will make last_array to point to the same elements of current_array, i.e, changing current_array will affect last_array and vice_versa.

var current_array = flow.get("current_array");
flow.set("last_array", current_array);
msg.payload = "set last array to current array";
return msg;

Try to use this statement to copy current_array to last_array:

last_array = [...current_array];

Only then you save last_array to the flow context

flow.set("last_array", last_array);

edit:

Therefore this is how your last function will looks like:

var current_array = flow.get("current_array");
last_array = [...current_array];
flow.set("last_array", last_array);
msg.payload = "set last array to current array";
return msg;
3 Likes

Alas, everything in the world makes sense again.
thank you!

1 Like

For those who want to understand better what it means passing by reference and the shalow copy solution from this post here is a good video: https://www.youtube.com/watch?v=duyshh9Fs1U

2 Likes

You saved my day. Thank you for this link.

1 Like