Wait for loop (subflow) to be finished

Hi,
I have an XML file in which several SVG files are specified (path and name). I want to edit these SVG files in a loop. This works so far.
As soon as this loop is finished, the XML file should be transferred to a Connect template as a job file. How can I achieve that?

I have tried to use the “complete” node but that does not work.

From the Complete node you should have access to your MSG from the previous flow.
Put a Debug node after your Complete node and look at the overall MSG.

Thank you for your reply.

I do not get it to work with the complete node. If I set the complete node to wait for “XML Loop” to be finished, the complete node will be executed before all iterations are done (I have verified this with a Date.Now() debug output in subflow and the complete flow).

My “XML Loop” node is a function where I iterate through one xml. Per iteration I use the following:

node.send({ payload: svg, focusLevelRgb: focusLevelRgb, svg_out: svg_out});

That works fine and per iteration the following nodes will be executed with the correct informations. Maybe I am using the loop wrong?

I also tried to convert the loop steps into a subflow. In my main flow I set the complete node to watch that subflow. But in that case the complete node will never be executed.

All I want is a synchronous flow in that case (execute a subflow before continue in the main flow).

Do you still have node.send() in the SVG Colors node as shown in the latest screenshot?
If so i would remove them since there is no output to that node no more.

Hi Thomas,

Interesting case, could you share your flow (via email)?

How about uploading the XML data to the OL Connect File Store using the file store upload node. This returns msg.managedFileId which the data mapper node or all in one node can take as input.

… > function (change SVG Color) > file store upload > all in one > …

The plan is to have the data mapper and all in one node to handle the data upload step for you. This is on our backlog.

Happy to give it a look.

Erik

Notice that your subflow has no Output anchor, you can enable that in the subflow. See the following image:

image

1 Like

@jchamel Yes, node.send() is in the SVG Colors subflow. I need that to loop over the xml attributes. Otherwise I have to do everything in the function. Of course I could do everything in one single function, because I activated/imported fs module, but I want to understand OL Connect Automate.

@Erik After adding an output and switch statement (in my function after my for loop I set msg.loopStatus to “ready”) to the subflow I can manage the further handling in my main flow. Now I stuck a bit on using the xml payload for Connect, but as you mentioned I think I have to use file store upload node before the all in one node.

I wonder if there is a better/easier way to loop through a xml and do some stuff before creating output through Connect. Is there any kind of loop node I do not see? Is it the correct way to use node.send() like I do?
It looks like a lot has to be done via scripting and/or a lot of steps (nodes) have to be used for cases like mine. In most examples the flows are very handy and straight forward. Unfortunately, we hardly ever have such simple cases. We often have to manipulate external files within a flow before creating output.

Basically, I like OL Connect Automate quite a lot, but I still find it a bit cumbersome for complex processes. Of course, this is also due to the fact that I have to get used to that new concept first.

Maybe you can give me a general advice how to create a flow like the following (old workflow)?

flow

Hi Thomas,

On this specific case: How about modifying the data as part of the Data Mapping configuration? In the end this loops over the records too. In that case you don’t even need to process the data in your flow. Happy to schedule a meeting to have look at this. Let me know,

Erik

Hi Erik,
in that specific case I have an unknown amount of images (path and file name) in a xml file, and I have to manipulate each image with individual informations (e.g. change colors). Do you suggest that I do the reading/writing of the external image files directly in DataMapper (TextReader/TextWriter)? To be honest, I haven’t tried that yet in this context, because its more handy in Workflow.

At the moment I’m just playing a bit in OL Connect Automate to get a better feel for it. I would like to get in touch with you in the future about a meeting, maybe with a few use cases that I could send you in advance. Would that be ok?

Thomas

Overlooked the fact that the XML was referring to images. I created a small example based on Node-RED techniques.

The flow reads an xml file and converts this to JSON. This allowed me to iterated over the array with image names using the “split” node (loop)

After the split I’m constructing the full path and read the svg data. A “change” node was used to do a simple find & replace action for hex values. After this the flow overwrites the svg data. The split node generates a sequence of msg objects, one for each entry in the array. The “join” merges things back to a single msg object after which the flow continues as normal.

Happy to schedule a meeting.

Erik

PS. Note that xml to json conversion can be configured via msg.options (this module uses xml2js). I set a few options to copy the attribute names holding the image names to a property. This makes it easier to access the data in other nodes.

The flow (hope it survives the pastboard ;)):

[{"id":"d0883d81f425af08","type":"inject","z":"883c72d4e34706f9","name":"","props":[{"p":"workspace","v":"C:\\workspace\\support\\hessler\\svg\\","vt":"str"},{"p":"filename","v":"msg.workspace & \"images.xml\"","vt":"jsonata"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":130,"y":2880,"wires":[["df437b1c6f3f65ed"]]},{"id":"df437b1c6f3f65ed","type":"file in","z":"883c72d4e34706f9","name":"","filename":"filename","filenameType":"msg","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":280,"y":2880,"wires":[["0fcca3b8c9732de0"]]},{"id":"d6c10c86cd738389","type":"debug","z":"883c72d4e34706f9","name":"debug 156","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1190,"y":2980,"wires":[]},{"id":"bddd8f583a8c79d3","type":"change","z":"883c72d4e34706f9","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.images.img","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":780,"y":2880,"wires":[["d1eda2044d4de4f9"]]},{"id":"d1eda2044d4de4f9","type":"split","z":"883c72d4e34706f9","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":270,"y":2980,"wires":[["1b84ca45b9dde493"]]},{"id":"0fcca3b8c9732de0","type":"change","z":"883c72d4e34706f9","name":"xml conversion options","rules":[{"t":"set","p":"options","pt":"msg","to":"{\"explicitArray\":false,\"mergeAttrs\":true}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":460,"y":2880,"wires":[["fa938a8592b83e09"]]},{"id":"fa938a8592b83e09","type":"xml","z":"883c72d4e34706f9","name":"","property":"payload","attr":"","chr":"","x":630,"y":2880,"wires":[["bddd8f583a8c79d3"]]},{"id":"e3c2332fae8d0d28","type":"file in","z":"883c72d4e34706f9","name":"","filename":"svg","filenameType":"msg","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":560,"y":2980,"wires":[["26c1e584e32f5f79"]]},{"id":"1b84ca45b9dde493","type":"change","z":"883c72d4e34706f9","name":"","rules":[{"t":"set","p":"svg","pt":"msg","to":"msg.workspace & msg.payload.name","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":410,"y":2980,"wires":[["e3c2332fae8d0d28"]]},{"id":"26c1e584e32f5f79","type":"change","z":"883c72d4e34706f9","name":"find & replace colors","rules":[{"t":"change","p":"payload","pt":"msg","from":"#ED2024","fromt":"str","to":"#DCD0FF","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":740,"y":2980,"wires":[["7da7e79dd579e4a4"]]},{"id":"7da7e79dd579e4a4","type":"file","z":"883c72d4e34706f9","name":"","filename":"svg","filenameType":"msg","appendNewline":false,"createDir":true,"overwriteFile":"true","encoding":"none","x":920,"y":2980,"wires":[["ca0f663f9ebf67ce"]]},{"id":"ca0f663f9ebf67ce","type":"join","z":"883c72d4e34706f9","name":"","mode":"auto","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":1050,"y":2980,"wires":[["d6c10c86cd738389"]]},{"id":"b9468909447b6bfc","type":"comment","z":"883c72d4e34706f9","name":"Read xml with array images","info":"","x":200,"y":2800,"wires":[]},{"id":"64d450b03d33362e","type":"comment","z":"883c72d4e34706f9","name":"Convert to JSON and use split node to loop","info":"","x":240,"y":2840,"wires":[]}]
1 Like

For your inspiration. Created three variants for this flow.

The first flow is the same as shown earlier, it contains the logic for the color replacement as part of the flow.

The second flow uses a subflow. For this I selected the respective nodes and turned those into a subflow via the Node-RED menu (Node-RED menu > Subflows > Selection to Subflow).

The third solution is to use the “link call” node which allows you to call a flow starting with the “link in” node. This can be a convenient way to organize your flow as you can keep the main flow and the “virtual subflow” on the same canvas/same view.

You could also have the split and join in your subflow or “virtual subflow” as shown below:

1 Like

Hi Erik,
many thanks for these examples! That helps a lot to understand OL Connect Automate.
I could succesfully create a flow to process my job. I really like the different ways of creating interdependent flows (via complete node, subflow, virtual subflow).
I am planning to switch some simple customer projects to OL Connect Automate as soon as the first official version will be released.

Thomas

1 Like