And this examble can become less complex if the loop is put inside a subflow
Lets be honest, it is a toy example.
I know you understand execution context and local variable life cycle.
It would not work with a lib that expects resolution within its execution to proceed. Not without a lot of boilerplate and hoops.
And when the message returns, and you need to be in the original function execution context to resolve it, it gets messy even before the data traverses mediums.
For the visuals, here is anthoer (toy) example in in both formats:
I know which one I prefer & the first version is MUCH easier to implement in terms of context management, cognitive load and whole lot less spaghetti.
Beer time guys
Iâd prefer the non-linkcall version when youâd use a link-out node after the link-call node. The link-out would link to a link-in node that flows into the function node, completing the loop.
That would remove the Spaghetti that you dislike. So i still donât see the use case.
And no iâm trying to be difficult but I still donât see an example which is only solvable with a linkcall in the function node. If this about âmy flow looks to complexâ then thatâs a different problem than âI was really canât solve this Problem with NRâ.
I never said "only" and never meant to imply that if I did.
(there are more)
FWIW:
I can already achieve pseudo node.linkcall by registering a function in global/flow context that emits a msg via node.send and that then links to a link-call (in dynamic mode). I then resolve that with a correlation id and a promise stored in context (or some other means - there are a few ways to skin this cat) but it is brittle and it makes me want to puke. I am trying to improve code reuse (and not only function code - reusable flows too) I really dont get the pushback!
Beer time for real now! Looking forward to the replies.
I did say this one was controversial, sorry if I have subconsciously triggered the debate ![]()
I would like to attempt, to end it like this:
- I'm thankful for the feature, as I am sure - this has massive potential for the right use case.
- Some will like it, others will not, some will use it, some will not.
And just to use another example.
- Some liked the need to use the close button on the tray
- Some did not
It's all progress, works for some, for some it won't
Indeed!
Have a beer, have a couple of beers - Please for Pete sake people!
Seriously though... enjoy the long weekend everyone ![]()
Similar to you not understanding the pushback (visual inconsistency, hidden data flows, extra bug searching looking for linkcalls in function nodes, breaking backward compatibility), I donât understand your hand waving trust me, we need this because i donât want to add too many nodes to my flows.
Every problem you have raised, have working alternatives, yet you say that you need this and therefore NR has to be changed for everyone.
Just saying, as much as you donât understand the pushback, I donât understand your reasoning for this ![]()
Again, if at least, this feature becomes visually presentable (i.e automatic grey lines of some kind), then I wouldnât see this as problematic. But even then, why have link out or link call nodes when I could use a function node, so perhaps remove those two nodes as well?
I do not think i called any one a name , i describe a group of people in the past that were resistant to a positive change, in my opinion.
I did not make the assertion that all change is good, but cheaper better quality clothing was in my opinion.
Strange comment, as node-red has multiple jobs and uses.
There are refrigerators that chill with out electricity, and use a different method. Therefore i see no issue with a function node calling to a linkcall, just a different method. You don't have to use it or any flows that use it if you wish, your choice. I for one will choose to use this method.
Nor should it on its own. I find the use positive you are welcome to your opinion to.
I've been offline most of today (and continue to be this weekend), but I've seen this discussion is straying away from the topic of the beta and getting a bit snippy with each other. Please keep on topic at hand.
No, I saw your comment after I had already wrote my feedback.
This reminds me of the saying "predicting the future isn't about being right tomorrow, it's about convincing someone today". So if this doesn't get used, will it be removed? Or will it add code that isn't used?
As I pointed out, if someone else now creates a function node, I have (if I include the function node in my flow) to check whether it uses this. So I can't decide not to use this feature if others might use it. So no, this isn't just one of those optional features, any flow from NR 5.x might include a function node that uses this and has "hidden" data flows that might cause bugs.
Why? Because any function looks like any other function node, there is no visual indication that it's using linkcall feature.
So no, hand waving and saying this will be fine isn't doing it for me.
Yep, so I didn't upgrade to 4.1 - fck it, until this can be deactivated, I won't use 4.1.x. I don't mind not upgrading. In fact, even this feature won't cross my path, so I genuinely don't care. Then this forum can also deal with the confusion that newbies will be facing when folks start using function nodes instead of link nodes - hell, why bother with a link call node when a function node will do.
And my initial comment of using a single function node is still relevant, why even bother with all the other nodes when one function node can do http request, write files, read files and has state? So giving the function even more functionality will increase that confusion: why use any other nodes when a function node will do?
That reminds me of
"doing more and more with less and less until you eventually do everywhere with nothing"
Looks spicy
![]()
This immediately makes me wondering who of us can create the most beautiful node-red-flow-art
I like the symmetry of this one.
It reminds me of an army, though.
Soldiers waiting for order.
With a king (timestamp) watching and pushing all of them.
And with a (joined) loop which indicates repetition and direction but without greater future.
I yet have to make my mind about how to interprete "do somerhing with the data from the linkcall" ... it could represent future without indicating progress? Mh. This will have me thinking the whole day.
My (own) favourite is the visual representation of a neural network:
that's a two layer ANN so very far away from todays LLMs but the basic concepts remain the same. (from this discussion).
But there is a lot to be said for what a flow looks like and whether it actually works - if a flow doesn't look "right" it will probably not work. Hence making it look right is a form of visual refactoring!
but that is fine since I can zoom in to get the node out of there or drag it by clicking on the botton of the node
However, I noticed that nodes placed there are not shown in the Mini map.
look the nodes vanish from the Mini Map
They start to appear around this height/y
To prove they disappeared from the minimap I moved the scroolbar and the minimap rectangle out of the way
Lets go...
Catch nodes, complete nodes, status nodes, even MQTT in nodes could be considered the same.
Not really, it promotes (or at least offers formalised support for) calling reusable flows.
Search is a users friend.
junctions, node.done(), node.path, env vars in a tab, env vars in global flow, etc.
Break eggs, make omelettes (or stay on V1 forever ;))
If a user does import a flow using this feature, they will see TypeError: node.linkcall is not a function. A forum or internet search will lead to the cause. Then they upgrade or use workarounds.
Trust me bro!
Not what I said but...
A way of calling functions (and flows/nodes) has been requested many times on the forum and other places.
The reason/rationale for the introduction of this is to offer a familiar / standardised design pattern that everyone can use (or not) in those times they are inside code execution and want to call out to common reusable code (or flow) routine.
The preference is still always use wires where sensible, but when the wiring logic and overhead becomes too complicated, there is now another option.
Again, I never said I "need this" and as already stated, I already have a working solution, but it is my implementation, using methods that completely bend the rules and is even more opaque than the a formalised feature like node.linkcall is offering.
So here is a more complete flow that demonstrates why I went to the effort of starting a discussion with proposals and then implemented a solution to formalise a better way of making & using utility functions (and flows) from within function code execution.
node-linkcall-demo.json (59.2 KB)
Note again for clarity, I have solved this already (running on Node-RED v4 without node.linkcall) but it is a drag, its brittle, opaque, hard to follow & is my own implementation - so I am genuinely interested to see how others would approach this in a visual/wired way.
the exception node has a select nodes button - that shows visual the nodes its listening to.
the complete node has the same button
the status node has the select nodes button
MQTT and HTTP Request both take data external from node red and pipe that into a flow, kind of hard to draw a wire for that.
Does the function node have or will have a select nodes button?
Not really? How is calling linkcall without a visual que a "not really"? It promotes calling reusable flows yes, but also this is hidden. It's not a "not really".
This reminds me of the diff tool built into NR - a column by column listing of changed attributes. A very textual solution for an essentially visual tool.
Found a bug in the dark theme.
The node.status fill of blue is shown as red.
The flow below shows all status colours, for both dot and ring.
[{"id":"3cb7a041e3402c81","type":"inject","z":"b1edeaff91acc38b","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":270,"y":340,"wires":[["93221f47b5d99903","79563c020369559b"]]},{"id":"93221f47b5d99903","type":"function","z":"b1edeaff91acc38b","name":"RED","func":"node.status({\n fill: \"red\",\n shape: \"dot\",\n text: \"RED\"\n});\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":430,"y":320,"wires":[["93fc162e9a68ed56"]]},{"id":"93fc162e9a68ed56","type":"function","z":"b1edeaff91acc38b","name":"GREEN","func":"node.status({\n fill: \"green\",\n shape: \"dot\",\n text: \"GREEN\"\n});\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":560,"y":320,"wires":[["a28f3b7381e40521"]]},{"id":"a28f3b7381e40521","type":"function","z":"b1edeaff91acc38b","name":"YELLOW","func":"node.status({\n fill: \"yellow\",\n shape: \"dot\",\n text: \"YELLOW\"\n});\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":700,"y":320,"wires":[["db25233780d80cce"]]},{"id":"db06b8a484e55c51","type":"function","z":"b1edeaff91acc38b","name":"GREY","func":"node.status({\n fill: \"grey\",\n shape: \"dot\",\n text: \"GREY\"\n});\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":950,"y":320,"wires":[[]]},{"id":"db25233780d80cce","type":"function","z":"b1edeaff91acc38b","name":"BLUE","func":"node.status({\n fill: \"blue\",\n shape: \"dot\",\n text: \"BLUE\"\n});\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":830,"y":320,"wires":[["db06b8a484e55c51"]]},{"id":"79563c020369559b","type":"function","z":"b1edeaff91acc38b","name":"RED","func":"node.status({\n fill: \"red\",\n shape: \"ring\",\n text: \"RED\"\n});\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":430,"y":380,"wires":[["4da1ef29b6fbed5d"]]},{"id":"4da1ef29b6fbed5d","type":"function","z":"b1edeaff91acc38b","name":"GREEN","func":"node.status({\n fill: \"green\",\n shape: \"ring\",\n text: \"GREEN\"\n});\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":560,"y":380,"wires":[["1a9b49942aa28c95"]]},{"id":"1a9b49942aa28c95","type":"function","z":"b1edeaff91acc38b","name":"YELLOW","func":"node.status({\n fill: \"yellow\",\n shape: \"ring\",\n text: \"YELLOW\"\n});\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":700,"y":380,"wires":[["f22b1061f8ead246"]]},{"id":"abeabb9f6833ecba","type":"function","z":"b1edeaff91acc38b","name":"GREY","func":"node.status({\n fill: \"grey\",\n shape: \"ring\",\n text: \"GREY\"\n});\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":950,"y":380,"wires":[[]]},{"id":"f22b1061f8ead246","type":"function","z":"b1edeaff91acc38b","name":"BLUE","func":"node.status({\n fill: \"blue\",\n shape: \"ring\",\n text: \"BLUE\"\n});\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":830,"y":380,"wires":[["abeabb9f6833ecba"]]}]
Post deleted.
Confirmed
















