What is the difference between this expressions

Sorry - I am new with JS. What is the difference between

msg.payload = 0;
return msg;

and

msg = {payload:0];
return msg;

and

return 0;

and maybe to discontinue the flow

return null;

:white_check_mark: 1. msg.payload = 0; return msg;

What it does:

Modifies the existing msg object (a standard Node-RED message).

Sets its payload property to 0.

Sends the updated message to the next node.

Use case: Most common way to manipulate a message and continue the flow.

msg.payload = 0;
return msg;

:white_check_mark: 2.

msg = {payload: 0}; return msg;

What it does:

Creates a new object with only a payload property set to 0.

Replaces the entire message with this new one.

Sends the new message to the next node.

Risk: You lose all other fields in the original msg (like topic, timestamp, etc.), unless you copy them manually.

msg = {payload: 0};
return msg;

:warning: 3. return 0;

What it does:

Returns the number 0, not a message object.

Node-RED expects a message object, so this will be ignored or cause an error depending on the node.

Result: Does not continue the flow correctly. Don’t use this unless you know the node can handle raw values (rare).

return 0; // :cross_mark: not valid in most cases

:white_check_mark: 4. return null;

What it does:

Explicitly tells Node-RED to not send anything forward.

Effectively halts the flow from this function node.

Use case: Conditional filtering. Only continue flow when certain conditions are met.

if (msg.payload > 50) {
    return msg;
} else {
    return null;  // Stops the flow
}

Summary Table

Code Message Sent? Notes
msg.payload = 0; return msg; :white_check_mark: Yes Keeps the rest of the msg intact.
msg = {payload: 0}; return msg; :white_check_mark: Yes Replaces entire message.
return 0; :cross_mark: No Not valid; return value must be a message object.
return null; :cross_mark: No Stops the message from flowing further.
10 Likes

Great table and explanations. If we like to pass more than one value to next node, we need to open a second dimension in the JSON object what seems normally the "topic" for NodeRed. Its also possible to use the topic with only one value.

msg = {payload:21}; // generates new JSON object with content 21

seems equal to

msg = {"payload":{"temperature":21}}; // generates new JSON object with content 21

The benefit for the topic temperature is now, to add a second value to the same msg.payload object separated by comma

msg = {"payload":
             {"temperature":21,
              "color":"green"}
           }

If last expression is followed by the one before, the topic color and its value green are lost as the new object overwrites the old. If we like to change color while keeping the temperature, we have to write

msg.payload = {"color":"blue"};

what is equal to

msg.payload.color = "blue";

If we like to add a new temperature topic to existing JSON msg what already contains topic "color" its

msg.payload = {"temperature":19};

Changing both values in case of existing JSON object is then

msg.payload = {"temperature":19 , "color":"blue"};

but is not possible to write if one of the topics is not existing.
Position of the topic:value pairs inside a JSON object seems a dont care.

msg.payload = { "color":"blue" , "temperature":19};

Hopefully this is all true what I understood and I do not have to amend too much. I certainly have practice and deal with to solve anything using NodeRed.

I am struggling with the use of topics. Why is the debug output format different and what is the difference at all? "green" ist not a JSON object while {"color":"green"} should be one.

[{"id":"2b88b27bd370a8f9","type":"tab","label":"Flow 2","disabled":false,"info":"","env":[]},{"id":"918531f828bf9a92","type":"inject","z":"2b88b27bd370a8f9","name":"ColorSensor","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"color","payload":"green","payloadType":"str","x":1270,"y":80,"wires":[["ab73115700b1d330"]]},{"id":"8f5b1d142230d240","type":"inject","z":"2b88b27bd370a8f9","name":"MeassureTemp","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":1280,"y":200,"wires":[["5b92be1fb26001dc"]]},{"id":"5b92be1fb26001dc","type":"function","z":"2b88b27bd370a8f9","name":"TempSensor","func":"msg =   {\"payload\":\n            {\"temperature\":21}\n        };\n\nreturn msg;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1470,"y":200,"wires":[["36784930c7326b4a"]]},{"id":"ab73115700b1d330","type":"debug","z":"2b88b27bd370a8f9","name":"debug 7","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1640,"y":80,"wires":[]},{"id":"36784930c7326b4a","type":"debug","z":"2b88b27bd370a8f9","name":"debug 8","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1640,"y":200,"wires":[]}]

Your use of "topic" is confusing.

In Node-red a message will very often have two properties: payload and topic
A property consists of a key and a value pair "key": value

Here the keys are payload and topic. The value for payload is itself an object with two key: value pairs.

{
"payload": {
   "author": "Beatrix Potter",
   "title": "The Tale of Peter Rabbit"
}"
"topic": "First Editions"
}

IF msg.payload is already an object then you can add or modify a property

msg.payload.title = "The Tale of Mr Jeremy Fisher"
msg.payload.price = 2750

Accepted. Probably my use of topic is not only confusing. My definition is simply wrong and not understood. What the hell is the output of the ColorSensor button? How do we have to change the TempSensor function code to get same format in debug window?

In the picture you posted above there is an inject node called ColorSensor.
The double quotes in the debug panel shows that it's output is a string green
The inject node is probably configured like this

The same format - a number?
msg.payload = 21
Or a string?
msg.payload = "21"

Inject node looks like this. temperature 21 is a number. Flow is attached before.

Your picture shows that the payload output from the function is not 21 but an object {"temperature": 21}

You might find the documentation Working with Messages helpful.

Finally I found the difference. It is possible to add the topic to the msg instead of the payload.
Version 1: Adding topic to the payload gives a JSON object

msg =   {"payload":
            {"temperature":21}
        };
return msg;

Version 2: Adding topic to the message is also possible and does not generate a JSON object

msg.payload = 21;
msg.topic = "temperature";
return msg;

Curly braces are main difference to produce nested JSON object.
Who said, Node Red should be easy?

Who said, Node Red should be easy?

It is, except that these are concepts of javascript.

{ payload: { temperature: 21, color: "green"}} // object
{ payload:21 } // number
{ payload:"hello"} // string

if you write:

msg.topic = "some topic"
msg = { payload:{ temperature: 21 } }
return msg 

You are overwriting msg with an object.

Instead you could write:

msg.topic = "some topic"
const payload = { temperature: 21 } 
msg.payload = payload
return msg

Now you have both a msg.topic and a msg.payload with an object.

None of what you are doing here requires you to use function nodes or write JavaScript.
You can the change node for most of this msg property setting stuff.

Beside NodeRed I lack of JavaScript. To be honest: I understimated JavaScript completely.

Probably there is everything possible using pre-manufactured NodeRed nodes. The libraries and custom contributions have thousands of specialized nodes possibly nobody has any overview. Nobody knows what custom nodes will be maintained in future. Therefore its a good combination to add own JS code to available nodes. At least while learning. Going back to the most simple operations before using any mighty black box node without understanding. Today I struggled to use the join node what required to watch several YT videos. After I understood above differences, I hope the join node will do soon what I expect.

Yeah, fair approach, however from what I have seen, you are starting off like i did (reach straight for the function node, using context, loops)

Once you get over that hump, you will find many of the core nodes (and a good set of contribs) are well thought out and reduce the need to pick the sledgehammer each time.

The join is simplest when you pass a split stream back into the join (in auto mode)

e.g. pass an array in payload [1,2,3,4] --> split --> change (add 10 to payload) --> join (default auto mode) --> debug [11,12,13,14]

Join node in manual mode take a moment to orient yourself but sufice to say, the defaults are normally what you want (e.g. join as an key/val object, join by topic)

A good resource for learning what the nodes do is built right into node-red.

CTRL-I -> examples -> node-red

1 Like

Is there any difference between 'return null;' and just 'return;' ?
I've been doing the latter for years, should I change?

No, whichever is more readable/ understandable to you.

2 Likes