Multiple output Function nodes with multiple messages

(And the fool continues to bash his head against the wall)

I've read this link (from search) Writing functions
and it is interesting.

I can sort of make it work, but when I try to apply it to the real flow, it doesn't.

This is an extract of the node:
Yeah, messy comments. I'm working on that.

        //  It is now given the machine is offline.   Clean up stuff.
        msg1  = {payload: '<font color = "red" i class="fa fa-bullseye fa-2x"></i>', host: host, topic:device + "/Off-line",device_ID:device, background:"brown"};
        msg2 = {topic: device, device_ID: device, state: 4, background:"brown" };
        node.warn("Sending only msg2 " + msg2);   //  This doesn't give me anything useful to check.
        //mode.warn(msg2);   //  this gives errors.
        return [[],msg2];

I want to send msg2 out of the second port/output of the node.

The last line works on another simple flow with 5 nodes. But it doesn't seem to want to play the game here.

Where's the elephant?


If I change the line so it is:

msg2 = {payload: "Test"};

and leave the rest as is, it works, as in I get "Test" coming out of the second output.

I am missing something.

Testing your function I got this error displayed in the debug node:

"ReferenceError: host is not defined (line 3, col 92)"

The function execution stops when hit this error. When you fix it you will see that all works well.

Well, given that all the names are defined in mine........

I even went as far as this:

        node.warn("Device " + device);
        node.warn("Device_ID " + device);
        msg2 = {topic: device, device_ID: device, state: 4, background:"brown" };
        node.warn("Sending only msg2 " + msg2);
        return [[],msg2];

I see this:

"Device PortaPi"
5/25/2019, 11:52:55 PMnode: Super Nodefunction : (warn)
"Device_ID PortaPi"
5/25/2019, 11:52:55 PMnode: Super Nodefunction : (warn)
"Sending only msg2 [object Object]"
5/25/2019, 11:52:55 PMnode: Button ColourPortaPi : msg.payload : undefined

So I am really missing something about the message "type" (format?)

Why do you return [,msg2]?
Why not return [null,msg2]?

I suspect sending an empty array in the first element may route the msg2 to the first output.

I think that gives the same result to me.

This is the BASE LINE flow:

[{"id":"67c45087.8a6f3","type":"inject","z":"15af81c5.64999e","name":"","topic":"","payload":"a","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":210,"y":3350,"wires":[["a92e0a0c.13e4"]]},{"id":"f71e3acc.9df94","type":"inject","z":"15af81c5.64999e","name":"","topic":"","payload":"b","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":210,"y":3400,"wires":[["a92e0a0c.13e4"]]},{"id":"a92e0a0c.13e4","type":"function","z":"15af81c5.64999e","name":"","func":"var msg1 = {payload: \"This is the first message\"};\nvar msg2 = {payload: \"This is message two\", colour: \"Blue\"};\nif (msg.payload == 'a')\n{\n    return [msg1, msg2];\n}\nelse\nreturn [[],msg2];\n","outputs":2,"noerr":0,"x":400,"y":3380,"wires":[["a271892b.ce759"],["69addc20.09dd2c"]]},{"id":"a271892b.ce759","type":"debug","z":"15af81c5.64999e","name":"Message 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":600,"y":3300,"wires":[]},{"id":"69addc20.09dd2c","type":"debug","z":"15af81c5.64999e","name":"Message 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":600,"y":3450,"wires":[]}]

I "cheated" and made the second message a bit more than just text.

If I press a, I see both messages out of their respective outputs.

Pressing b I see the second message out of output #2.

But...... On the machine with the flow, it just spits the dummy at me.

I just tried what you said about the return [null,msg2].

Same result. It works, on the test flow.
Not on the one I want it to work on.

So, your test flow shows that you fully understand how to send multile messages. You created a fully functional test flow (that would be nicer if you were using the null statement instead of an empty space).
If I got it right you came to the conclusion that your main flow is bugged ?

I'm not in a position to test your flow but it would seem the problem is before the return. My guess is you have a bug somewhere that ends up with msg2.payload not being populated or being assigned an undefined value. You should look around the logic that populates msg2.payload. Double check all paths are covered.

When you say it doesn't work, what do you mean? What do you see when you put debug nodes on the outputs?

Ok, sorry folks. It was late last night. Got some sleep and am back at it this morning.

The flow is complicated - as they usually are.

I know this is going to be way off track, but it may help with the bigger picture.

Most of the machines (RPIs) connected to the network send data back to the main machine.
Ping, Temperature, CPU load.

The Ping and Temperature work together to give an ONLINE signal.
If the machine is OFFLINE, the Ping returns a signal indicating that.

If the machine is ONLINE, that signal is re-sent every interval indicating the state as online.
One of those outputs from the first SUB-FLOW is sent to the second SUB-FLOW and that is used to set the colours of the buttons.

All things being nice, everything is happy and the buttons reflect the correct state.

Because I got too smart for myself I over optimised the code and lately I discovered that the OFF-LINE signal is only sent TWICE when the device goes off line.

Thus, if the screen is refreshed (or what ever) the button colour is lost.

Originally everything works fine and what is sent out the node is correct. (Or to the best of my knowledge.)

What I am wanting to do is keep output #2 of the first SUB-FLOW sending it's data so the second SUB-FLOW gets the right information (repeatedly) to set the button colour.

The picture:
There are inputs to "Device status" (sub-flow) and it's second output (blue arrow) goes to the second sub-flow input. (Button colour)
"Button colour"'s #2 output is used to set the button colour.

I have done stuff with multiple outputs from a function node and they work.

But this is different in that the message is not a simple msg.payload = "something"
It has other parameters. And I agree I am probably stuffing myself with them.


The line/s for the output are pretty much copy/pasted from other lines which do work.
I've found it better to copy/paste from working lines than to retype them, as that increases the possibility of mistakes happening.

So: Lines which work and copied to another line and when it is sent errors happen.
JSON errors.
Making the line a simple one like I said: it works.

As is, the "it doesn't work" part means when I look at the debug window from the output node, I just get undefined if it is the complex one. (colours, and other variables included in the message body)
If it is the simple one, I get the text.

I'm not sure if that is helpful or not.

I'll stop here in case it isn't and no more information from this line of thought is not needed.


Ok, after a lot of study and checking things, I got it working.

The line of interest was not really changed.

This is the part of the flow of interest:

        //  It is now given the machine is offline.   Clean up stuff.
        msg1  = {payload: '<font color = "red" i class="fa fa-bullseye fa-2x"></i>', host: host, topic:device + "/Off-line",device_ID:device, background:"brown"};
        msg2 = {topic: device, device_ID: device, state: 4, background:"brown" };
        return [msg1, msg2];

Ok, I was doing more like: return [[],msg2]; or return [null,msg2];
Both (originally) yielded undefined. Now it works.
Maybe the inclusion of msg1 helped.
(Shrug) I don't know.

But now it is behaving itself.

I can guarantee that if you change the return [msg1,msg2] to return [null, msg2] it will have no effect on what comes out of o/p 2. At least for the first message. It is possible of course that having nothing on o/p 1 may cause an error later on.

Yes, well....... I can't refute that now.

It is working.

At one stage when I was looking at the #2 output of the node in the real flow I was getting undefined.

But on the test flow I made it worked. Though that gave a simple text only output, rather than a message with extra bits.

Now it is working.

Do you mean it was sending a message with something in it undefined? If so then that was nothing to do with how you were sending it, it was what you were putting in it before sending it.

Correct. The debug node simply kept saying undefined when a message was supposed to be going out.

If you say.

The message was constructed in the node. It was basically a copy/paste from another line which did work.

But as I said: It is now academic. The node is doing what I want. Though the new dashboard would have resolved the problem I read.

But I got it working. When I get time I may look at it more and try to work out what was going on.

If something was appearing in the debug sidebar then a message was definitely bring sent. And if it said undefined then the message you were sending did not have a payload property.

Sending a message without a payload is not the same as sending no message at all.

I again agree.

But this is/was the line:
(Though I can not be 100% sure)
as it was but it has since been changed.

msg2 = {topic: device, device_ID: device, state: 4, background:"brown" };

This is the new line:

msg2 = {topic: device, device_ID: device, state: 4, background:"brown" };

But looking at it, it is the same.

The only thing changed is the line after it:

(can't find one. The old version got wiped)


        return [msg1, msg2];

Some of the things I tried are/were - I think:

return [[],msg2[]];
return msg2[];
return null,msg2[];

Those are all three wrong.
I use this regularly in my flows so can with certainty say that
return [null, msg];
Is the correct syntax.

@JGKK Pretty sure he knows by now. You are responding to a post from May.

1 Like

:see_no_evil::joy: thanks and have a nice day, Johannes