Apologies if this has been mentioned before -- I am further behind than usual in reading the forum.
When possible, I avoid using global variables by attaching state information to each message. I recently built a flow with some complex logic that was not producing the messages I expected in certain cases. Using a complete
node attached to a debug
node, I could catch the messages as they passed through each function
and change
node in the flow and so was able to see each message as it was modified at various points and find the problem.
This flow gives the general idea:
[{"id":"618b1cf1.6df17c","type":"inject","z":"42e9cb90.fa9734","name":"inject","topic":"testing complete node","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":280,"wires":[["d6ea6b13.304ce8","ed2f9d3d.1bcef8"]]},{"id":"17d0a463.499f2c","type":"debug","z":"42e9cb90.fa9734","name":"function output","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":460,"y":260,"wires":[]},{"id":"fa3c7acb.30e618","type":"complete","z":"42e9cb90.fa9734","name":"","scope":["d6ea6b13.304ce8","ed2f9d3d.1bcef8"],"uncaught":false,"x":110,"y":360,"wires":[["1d04b428.2c777c"]]},{"id":"1d04b428.2c777c","type":"debug","z":"42e9cb90.fa9734","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":250,"y":360,"wires":[]},{"id":"d6ea6b13.304ce8","type":"change","z":"42e9cb90.fa9734","name":"","rules":[{"t":"set","p":"time","pt":"msg","to":"payload","tot":"msg"},{"t":"set","p":"payload","pt":"msg","to":"topic","tot":"msg"},{"t":"set","p":"foo","pt":"msg","to":"bar","tot":"str"},{"t":"set","p":"topic","pt":"msg","to":"change node output","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":280,"y":300,"wires":[["c90a3799.49fe6"]]},{"id":"ed2f9d3d.1bcef8","type":"function","z":"42e9cb90.fa9734","name":"dummy function","func":"\nreturn msg;","outputs":1,"noerr":0,"x":280,"y":260,"wires":[["17d0a463.499f2c"]]},{"id":"c90a3799.49fe6","type":"debug","z":"42e9cb90.fa9734","name":"change output","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":460,"y":300,"wires":[]}]
Before making a habit of this, I have a few questions:
- Are there obvious down sides to using
complete
as a debugging tool in this way? - Is this behavior likely to change in the future?
- Are there core nodes in addition to
function
,change
, anddebug
that have implemented thedone()
function? - Would it be possible to add
done()
to other core nodes that transmit messages, likelink
,delay
, andtrigger
, or that generate messages likeinject
,range
andrandom
?
Also, a couple of observations, illustrated by this flow:
[{"id":"c39db174.4b3d2","type":"complete","z":"f953caa6.ca00c","name":"","scope":["119e8e79.9e8012","171cafbb.ddde5","b1af9e2c.05fcc8"],"uncaught":false,"x":150,"y":240,"wires":[["8b9484f6.1ad448"]]},{"id":"5a2dbdb6.575ee4","type":"inject","z":"f953caa6.ca00c","name":"","topic":"empty function and debug","payload":"hello world","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":140,"wires":[["171cafbb.ddde5","119e8e79.9e8012","b1af9e2c.05fcc8"]]},{"id":"119e8e79.9e8012","type":"debug","z":"f953caa6.ca00c","name":"empty debug","active":false,"tosidebar":false,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":310,"y":140,"wires":[]},{"id":"171cafbb.ddde5","type":"function","z":"f953caa6.ca00c","name":"empty function","func":"","outputs":0,"noerr":0,"x":320,"y":100,"wires":[]},{"id":"8b9484f6.1ad448","type":"debug","z":"f953caa6.ca00c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":290,"y":240,"wires":[]},{"id":"b1af9e2c.05fcc8","type":"function","z":"f953caa6.ca00c","name":"function (no output)","func":"msg.payload = \"goodbye world\"\nmsg.topic = \"not empty function\"\nmsg.foo = \"bar\"","outputs":0,"noerr":0,"x":330,"y":180,"wires":[]}]
- Both the
function
anddebug
nodes will send a message to thecomplete
node even when they do nothing to the input message and have no output. - The function node can modify the message sent to the
complete
node even when it has no output. - If the
complete
node is allowed to catch output from its attacheddebug
node, you get a loop.