I am the owner of node-red-contrib-components and got a bug report regarding components being used inside subflows. Working on the bugfix I find, that the "component_in" nodes don't receive custom events, that are sent when actually triggering a component to run.
Is that on purpose?
Is there a work around?
What events do you mean? You need to give more context.
But things like the button on the inject node will not work, because what you see in the editor is the subnode template that all instances are based on, not the actual instances in each subflow, so if you clicked the button it would not know which of the subflow instances it was meant to trigger.
well, it's a bit tricky, so more context.
Let me explain the nodes, so you have a chance to understand.
The components are reusable flows, very much like node-red-contrib-actionflows or even subflows.
There are two nodes to define the flow:
component_in -> component_out (return):
The third node is the "component" (run) node, that triggers the flow defined. It refers to one "component_in" node and sends an event to it using the RED.events.emit() method.
The "component_in" receives the event and starts executing the flow. The "component_out" takes the final message and sends another event back to the calling "component" node. Of course, there can be multiple "component" nodes, as that is the idea of reusing the component's flow.
Now it is possible to put the component definition into a subflow. To be honest, I have no idea why it is a good idea, but I am generally open to allow that, instead of denying. It sort of makes sense to me, if both the component definition and the usage all lay inside a more complex subflow:
And even if the component is used (called by a calling node) outside the subflow, it would still be logical to allow it, since there is no immediate result coming out the component's flow, that would need to know the instance of the surrounding subflow. The result of the component's flow is just sent back via an event to the callee and will be passed on to its connected nodes (which are not in the subflow):
So if we accept the idea to have components in a subflow, we come back to the technical possibilities of the NR runtime. And as it seems, NR explicitly does not consider nodes inside a subflow to be valid receivers of RED.events.emit() events, although the exact same node type will receive those events if it located in a tab (flow).
If that is the case, I would have to prohibit the usage of component definition nodes inside subflows (and probably show them to be invalid in that case).
But if there is a way to receive those events nevertheless, I would be happy to learn about the way.
That is not correct.
What event are they listening for? How are you generating the event name?
The events sent in the calling "component" node are composed by a prefix "comp-" and the id of the calling node.
The "component_in" registers itself using just the "comp-" prefix. I know, that this is not an exact 1:1 match, but I think I saw that in some other project (maybe in actionflow, but I don't remember). That seems to work pretty well, although today I saw while debugging, that the nodes also receive some other events, that come from other nodes. Until today I assumed, that the event emitter is just checking an event based on a gracefull match, so that "comp-12345678" is sent to a handler listening on "comp-".
You will probably tell me, that this is nonsense
So how exactly do the event names work?
Event emitters just do simple string matching between the name of the event being emitted and the names listeners are registered for.
A prefix followed by its id? If so, that is the problem.
When the runtime instantiates an instance of a subflow it creates a copy of the subflow template and generates new IDs for all of the nodes within it.
That means the ids of the component_in nodes will not be the IDs of the nodes in the template. Any node trying to 'call' one of those nodes using its id will not work.
This is the same reason you cannot us link nodes to jump into a subflow.
Given each subflow instance is a whole new instance of all nodes within it, that means your component will be instantiated multiple times - that probably isn't what you'd want.
thanks for the explanation!
It became clear now to me, that after all it doesn't seem to be a good idea, as we are mixing two solutions for a similar goal. Even if it was possible to find a work around, it smells like a bad thing to do. I feel side effects and lots of debugging coming this way.
I will prohibit using the definition nodes in subflows. They are meant to be an alternative to subflows in the first place.
The discussion was very helpful, as I think, I should refactor the event names and use the event's msg to transport the ids back and forth. So we will have fixed "start-component-flow" and a "return-from-component-flow" event names.
Thanks for your time and help!
This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.