How to get the count of incoming node flow lines

Is there a way of getting the count of the number of incoming lines to a function node?

For example if I had a function node with three input nodes linked to it, is there any code I can use in the function to count the number of nodes? I'm interested because I'm trying to create a customised version of a join node that can dynamically calculate the number of message parts to wait for to ensure that it has one from each incoming node before generating an output.

No not easily. How nodes are wired together is held by the node for the outgoing side - so you can tell how many you are wired to on the output side... but not on the input side.

(In theory on of the tenets of flow based programming is that nodes should be independent of each other and act a bit like black boxes - but yes there examples where that isn't the case :slight_smile:

You could store the true or false value of the context stored values.
and compare that to the property count of the context store for the join.
So when one wire connected it will pass every message, but as soon as you add a second with a unique topic ( and a message has be sent by the wire), then it has to receive two topics before passing. When message is sent it will set all context store trues to false, so resetting for next pass. here is an example.

[{"id":"c8f1c8ed.f36cb","type":"inject","z":"b779de97.b1b46","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"one","payload":"#undefine","payloadType":"str","x":270,"y":3100,"wires":[["9c7b1694.82b65"]]},{"id":"9c7b1694.82b65","type":"function","z":"b779de97.b1b46","name":"","func":"if(msg.payload === \"#undefine\"){\n    context.set(\"store.\" + msg.topic, undefined);\n    //return null;\n}else{\n    context.set(\"store.\" + msg.topic, [msg.payload,true]);\n}\nlet store = context.get(\"store\");\nlet store_true = Object.values(store).filter(e => e[1] === true).length;\nlet store_length = Object.keys(store).length;\n//node.warn(store_length +  \" - \" + store_true);\nif(store_length === store_true){\n    msg.payload={};\n    for( const k in store){\n        msg.payload[k] = store[k][0];\n        //node.warn([store[k][0],false]);\n        context.set(\"store.\" + k + \"[1]\", false);\n    }\n    return msg;\n}\nreturn null;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":430,"y":3240,"wires":[["71ce21dc.3f43a"]]},{"id":"a312c696.a5b76","type":"inject","z":"b779de97.b1b46","name":"one","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"one","payload":"$ceil($random()*100)","payloadType":"jsonata","x":250,"y":3240,"wires":[["9c7b1694.82b65"]]},{"id":"35ee5dc.934a3a2","type":"inject","z":"b779de97.b1b46","name":"two","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"two","payload":"$ceil($random()*100)","payloadType":"jsonata","x":250,"y":3280,"wires":[["9c7b1694.82b65"]]},{"id":"71ce21dc.3f43a","type":"debug","z":"b779de97.b1b46","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":590,"y":3260,"wires":[]}]

[edit] fixed, had return in wrong place, and not outputting to msg. Added example of removing a wire.

Dynamic count is possible only if incoming messages are created with respect of rules the node accepts. There is no magic.

1 Like

The number of occurrences of a particular node ID in flows.json will be 1 more than the number of wires connected to the input. (ie the node's definition and each node which links to it).
So it is possible to work out the number of links by using grep and wc -l.

(exec node returns 4 in that example)
But I don't think it's a very useful number to derive, not least since the message has already left the function node by the time it's calculated.
Even if you did know the number of inputs a simple count doesn't trap multiple messages from one input and none from another.

Much better to set context flags based on a property such as msg.inputName (is that what E1cid suggested?)

Thanks all. I will try out a few of these suggestions later and let you know how I get on.