Bug updating global arrays

#1

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":[[]]}]
0 Likes

#2

Kristin,

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

1 Like

#3

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

How do I make a copy of a global object without changing it?
#4

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

1 Like

#5

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

0 Likes