A do-node and corresponding return-node for creating loops and task-lists.
Do-RED is a toolkit which makes life easier within Node-RED:
- Two simple nodes (
do-return) allow to define loops, task-lists and - as a goodie - no-ops. It helps structuring your flows by preventing crossed loop-wires and endless flows. (Take a look at the samples below to understand what I mean. You find the sample flows in the doc-folder as well.)
- The documentation-first-approach helps to create understandable and maintainable flows.
- Navigating through your flow gets easier with the
- New feature "Each mode": Iterate through a collection and do the task list for each value.
Documentation first approach
With do-RED you can start by outlining and documenting your flow before you implement the real functionality. This documentation first approach helps you breaking down complex flows and ensure that others will have it easier to understand it.
Do-RED supports this approach by having the default for the do-node to be a no-op-node. This means that inserting a do-node into your flow (e.g. using the
do:append-do-node-action) will not change its behaviour unless your flow depends on message runtime. You can easily rename nodes with the
do:rename-node-action and change a node to another node-type using the
do:replace-node-with-action. The best: When you replace a node, properties of the original node are copied to the new one in case they are supported by the new node (usually at least the name, documentation and output-labels).
Navigating through the flow
It can be annoying to always have to switch between the mouse and the keyboard. So Do-RED adds some actions to navigate through your flow using the keyboard: Going left and and right is quite easy. But how does Do-RED determine which link to follow? Navigating forward, Do-RED always takes the upper most (linked) port and there the one which ends in the upper most node. And backwards always the link ending in the uppermost node is taken.
If you want to follow another link, you can switch to the next or previous link navigating up and down. As the direction your cursor took makes an important difference, the node you were coming from is highlighted.
Loops are the most basic usecase for the do-return-nodes. Just drag the do-node onto the canvas and wire its first output (task output) to whatever shall be repeatedly done and the second output (done-output) to where the flow shall continue after the loop ended. Using the return node you can decide whether you want to execute the loop once again (continue mode) or to end it (done mode).
Another usecase is for doing several tasks sequentially on a message. Therefore you need to add more task-outputs in the do-node (by adding tasks in its configuration). Each time a return-node in done-mode is called, it returns to the do-node and continues with the next task. Again, returning in continue-mode loops the current task.
You can abort a task-list at any time by returning in abort-mode. In the below example the balloons get painted red but in case a balloon is already red, it immediately aborts as this should not happen.
Instead of sending your whole message through the tasks you can also send each value from a collection through each task. For example: If you have an array you would send your first value through all the tasks. Then the second value and so on....
With the return node you can decide if you only want to read your collection or replace the current value with msg.payload. The iteration will only go through the original length/size of your collection.
Warning: If you change the index of an array (index-value pair), the value of the original index will be set to undefined. If you set the value of an object to undefined, the key will be deleted.
Tips & tricks
- Do-return-loops can be nested. But be careful not to mess with your flow: It can get hard to identify which return node corresponds to which do-node. For a better understanding you should name them correspondingly.
- The same tasks can be triggered by different do-nodes. The return-node knows where to return to during runtime. This can be helpful to define kind of construction plans using todo-lists which execute the same actions but in a different combination. See the 4th example (overlapping task lists) to get a better impression of what I mean.
- Aborting is an easy way for error handling within complex tasks: You might set an error-information within the msg-object and abort at any time. On the done-output of the do-node you can then check for errors and handle them appropiately or continue normally if no error-information is present.
- You might want to use todo-lists for structuring your flows top-down instead of having endless linear flows or very long return-wires.
- (Temporarily) restructuring complex tasks might get easier as you do not have to move all flows but only have to change the wires going out from the do-node.
- A do-node with no task is called a no-op-node and might help to create many-to-many-connections without having to use a function-node (thus easier to realise and maybe visually more appealing).
- Attention: Do not leave outputs unconnected! If no return node is connected to an output, this output will stop the flow. Also: If an output only ends in continue-nodes, you will build an infinite loop. Thus, each output should end in a 'done' sometime.
do:append-do-node-action always takes the first free port (or the first port if all ports already have links). So can easily append nodes and change them to whatever you want using only your keyboard.
- The path you navigated is remembered as long as you do not change the selected node using the mouse. This allows to follow a defined path forward and backward and you do not have to manually change it going up and down all the time.
do:append-do-node-action automatically extends the navigation path.
- Done output Your default list has a separate done output. If you want to end your list with the last task you can remove the done output by unchecking that option.
Created with SIR.
With help of SIR you can handle create node files with svelte which makes the code much cleaner and easier to handle.