Function with 2 output giving troubles

Hi

I have a larger function block that wasn’t working with 2 outputs.

I made it as short as I could and still produce my problem.

[{"id":"4b2b5008.c221f","type":"function","z":"b7656499.b2541","name":"Msg Test","func":"var OneMsg = msg;                                                  // The msg for setting light options\nvar TwoMsg = msg;                                     // The msg for setting manual override state\nOneMsg.debug = \"One\";\nTwoMsg.debug = \"Two\";\n\n\n\nreturn [OneMsg, TwoMsg];\n\n\n\n","outputs":2,"noerr":0,"x":940,"y":4260,"wires":[["58016c40.285fa4"],["6abf617d.ab492"]]},{"id":"58016c40.285fa4","type":"debug","z":"b7656499.b2541","name":"Debug OneMsg","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1120,"y":4240,"wires":[]},{"id":"8c35633e.b277b","type":"inject","z":"b7656499.b2541","name":"Input","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":810,"y":4260,"wires":[["4b2b5008.c221f"]]},{"id":"6abf617d.ab492","type":"debug","z":"b7656499.b2541","name":"Debug TwoMsg","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1120,"y":4280,"wires":[]}]

I input a payload, put it into 2 variables and add a msg.debug with a value to each output variable.
Expecting each output to be different, they are however the same.

Javascript as follow:

var OneMsg = msg;                                                  // The msg for setting light options
var TwoMsg = msg;                                     // The msg for setting manual override state
OneMsg.debug = "One";
TwoMsg.debug = "Two";

return [OneMsg, TwoMsg];

Producing

image

Your javascript is the problem here.

Because you are merely assigning a reference in var OneMsg = msg; and the same reference to var TwoMsg = msg, your next two lines are overwriting each other on the original msg object.

If you want to have separate message objects, you need to at least shallow-clone one or both:

var OneMsg = { ...msg }; // spread operator makes a shallow clone of the top-level keys onto a new object
var TwoMsg = { ...msg };
// ...
[{"id":"1b3d6d37.3b7df3","type":"function","z":"818f7407.1c85c8","name":"Msg Test","func":"var OneMsg = { ...msg };                                                  // The msg for setting light options\nvar TwoMsg = { ...msg };                                     // The msg for setting manual override state\nOneMsg.debug = \"One\";\nTwoMsg.debug = \"Two\";\n\n\n\nreturn [OneMsg, TwoMsg];\n\n\n\n","outputs":2,"noerr":0,"x":340,"y":1580,"wires":[["617ef510.7651dc"],["15ef1a66.ad75e6"]]},{"id":"617ef510.7651dc","type":"debug","z":"818f7407.1c85c8","name":"Debug OneMsg","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":520,"y":1560,"wires":[]},{"id":"46704e79.2166a","type":"inject","z":"818f7407.1c85c8","name":"Input","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":210,"y":1580,"wires":[["1b3d6d37.3b7df3"]]},{"id":"15ef1a66.ad75e6","type":"debug","z":"818f7407.1c85c8","name":"Debug TwoMsg","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":520,"y":1600,"wires":[]}]

Doing that, it should work as you expect:

1 Like

Hi
Thanks for your quick reply!

You really peaked my interest here!
Can you tell me more of this reference function? Maybe link for dokumentation?

I’ve coded javascript for more then 15 years and this is completely new for me, but my findings support your description.
I was considering a function like you descripte but I’ve never run across it before, I just got the result.

It’s the object spread syntax, part of ES6.

Thank you

This article explained it somewhat stupidified for me :slight_smile:

This is because JavaScript arrays and objects are reference data types. Unlike primitive data types, they point to the memory address where the actual object/array is stored.

And this

@paulstronaut Did you notice that the syntax check reports an error/warning?

image

It seems to work fine though :slight_smile:

Hah. That’s funny, since I use it all over in my node-red functions. It looks like the Ace editor (which uses jshint) isn’t as up to date with javascript as it should be (node-red requires node >= v8.0.0, which has destructuring)

If you don’t like the warnings Object.assign will probably pass jshint and do the shallow copy.

const oneMsg = Object.assign({}, msg);