Nested loop, how to

Hi all,

I'm going crazy with loops. I'm trying to implement nested loops into a recursive API requests system.
I can't find a solution. Can anyone could help me ?

Thanks a lot.
.Christian

I create something simple to understand how to do that...

[{"id":"7f5f20d.d5e58e","type":"array-loop","z":"9c2df3b0.58155","name":"array-loop","key":"al1a60a19a718526","keyType":"msg","reset":false,"resetValue":"value-null","array":"array","arrayType":"msg","x":1200,"y":1520,"wires":[["971350a4.6ab3f"],["724715e9.b3f0ac"]]},{"id":"c2e623b7.ffaef","type":"inject","z":"9c2df3b0.58155","name":"msg.payload = \"A, B, C, D, E\"","props":[{"p":"payload","v":"A, B, C, D, E","vt":"str"},{"p":"topic","v":"","vt":"string"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"A, B, C, D, E","payloadType":"str","x":720,"y":1520,"wires":[["b9ea69d8.8475b8"]]},{"id":"971350a4.6ab3f","type":"debug","z":"9c2df3b0.58155","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1370,"y":1520,"wires":[]},{"id":"b9ea69d8.8475b8","type":"change","z":"9c2df3b0.58155","name":"split msg.payload by \", \"","rules":[{"t":"set","p":"array","pt":"msg","to":"$split(msg.payload, ', ')","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":980,"y":1520,"wires":[["7f5f20d.d5e58e"]]},{"id":"a7237b14.0d86f8","type":"function","z":"9c2df3b0.58155","name":"return msg","func":"\nreturn msg;","outputs":1,"noerr":0,"x":1140,"y":1605,"wires":[["21f7367f.5a60ba","5206cc04.1b85d4"]]},{"id":"21f7367f.5a60ba","type":"debug","z":"9c2df3b0.58155","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1535,"y":1595,"wires":[]},{"id":"724715e9.b3f0ac","type":"delay","z":"9c2df3b0.58155","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":980,"y":1605,"wires":[["a7237b14.0d86f8"]]},{"id":"5206cc04.1b85d4","type":"function","z":"9c2df3b0.58155","name":"new loop","func":"msg.test = \"1, 2, 3, 4, 5\"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":920,"y":1710,"wires":[["11a73a64.bc4036"]]},{"id":"11a73a64.bc4036","type":"change","z":"9c2df3b0.58155","name":"split msg.payload by \", \"","rules":[{"t":"set","p":"array","pt":"msg","to":"$split(msg.test, ', ')","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1130,"y":1710,"wires":[["19b946d4.6576b9"]]},{"id":"4d63e81e.371b68","type":"delay","z":"9c2df3b0.58155","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":1320,"y":1805,"wires":[["3d650ec4.068082"]]},{"id":"3d650ec4.068082","type":"function","z":"9c2df3b0.58155","name":"return msg","func":"\nreturn msg;","outputs":1,"noerr":0,"x":1480,"y":1805,"wires":[["19b946d4.6576b9","3a1722e7.88860e"]]},{"id":"19b946d4.6576b9","type":"array-loop","z":"9c2df3b0.58155","name":"","key":"al8d749521bb8678","keyType":"msg","reset":false,"resetValue":"value-null","array":"array","arrayType":"msg","x":1380,"y":1690,"wires":[["1cf24671.3f45ca","7f5f20d.d5e58e"],["4d63e81e.371b68"]]},{"id":"1cf24671.3f45ca","type":"debug","z":"9c2df3b0.58155","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1590,"y":1685,"wires":[]},{"id":"55840ea2.48953","type":"inject","z":"9c2df3b0.58155","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":670,"y":1705,"wires":[["5206cc04.1b85d4"]]},{"id":"3a1722e7.88860e","type":"debug","z":"9c2df3b0.58155","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1690,"y":1805,"wires":[]}]

Hi, in order to make code more readable and importable it is important to surround your code with three backticks
```
like this
```

You can edit and correct your post by clicking the pencil icon.

See this post for more details - How to share code or flow json

Thanks a lot

no body ?

Can you explain exactly what this is trying to do? Then someone may be able to help.

I simply want to do a simple workflow with nested loops as in the example posted previoulsy.
The loops are based in simple arrays.

The target is to do multiples REST API calls, and each one do a new call with dynamics urls.

The problem isn't in the calls, but in the array loops. I have tried various nodes for the loops based on the array. All works prefectly with one level, but if you try to implement sub levels (nested loops) they don't work I think. But I maybe miss something...

Thanks a lot.

I haven't used the array loop node, so I was hoping for a more detailed example of exactly what you want to achieve so I could suggest an alternative.

[Edit] If you have a structure of nested arrays and want to call an api based on the contents of the array then personally I would do this with a function node rather than complex looping in the flow, I believe that would be a much cleaner solution.

You dont need to loop. use split nodes.

I have imported your existing flow but it makes very little sense so some guess work has been applied...

flow...

output...

flow json...

[{"id":"c2e623b7.ffaef","type":"inject","z":"529f171e.8d6188","name":"msg.payload = \"A, B, C, D, E\"","props":[{"p":"payload","v":"A, B, C, D, E","vt":"str"},{"p":"topic","v":"","vt":"string"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"A, B, C, D, E","payloadType":"str","x":180,"y":560,"wires":[["fbeba5de.5172b8"]]},{"id":"5206cc04.1b85d4","type":"function","z":"529f171e.8d6188","name":"make URL","func":"msg.payload = `http://${msg.loop1}/${msg.loop2}`\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":870,"y":620,"wires":[["65e2dbb9.8146b4"]]},{"id":"fbeba5de.5172b8","type":"split","z":"529f171e.8d6188","name":"Split on \", \"","splt":", ","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":410,"y":560,"wires":[["367774aa.b9711c"]]},{"id":"7361a450.8786ec","type":"change","z":"529f171e.8d6188","name":"set msg.payload = \"1, 2, 3, 4, 5\"","rules":[{"t":"set","p":"payload","pt":"msg","to":"1, 2, 3, 4, 5","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":930,"y":560,"wires":[["f3f6b013.1a14d"]]},{"id":"f3f6b013.1a14d","type":"split","z":"529f171e.8d6188","name":"Split on \", \"","splt":", ","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":410,"y":620,"wires":[["988c459f.617ba8"]]},{"id":"367774aa.b9711c","type":"change","z":"529f171e.8d6188","name":"move msg.payload to loop1","rules":[{"t":"move","p":"payload","pt":"msg","to":"loop1","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":640,"y":560,"wires":[["7361a450.8786ec"]]},{"id":"988c459f.617ba8","type":"change","z":"529f171e.8d6188","name":"move msg.payload to loop2","rules":[{"t":"move","p":"payload","pt":"msg","to":"loop2","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":640,"y":620,"wires":[["5206cc04.1b85d4"]]},{"id":"65e2dbb9.8146b4","type":"debug","z":"529f171e.8d6188","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1070,"y":620,"wires":[]}]

Thanks a lot Steve-Mcl.

You provide me a solution who solve my problem by a different way, but it don't answer my question.
How to loop over nested arrays ?

Many thanks.

Firstly, your question may have said "nested" & this ^ question asks about nested arrays HOWEVER your data / problem has no such nested arrays in it? A more accurate question would be "how to split 2 separate CSV values and create a URL from each one"

If you REALLY want to loop through a nested array then my advice is DONT (use split nodes as I demonstrated) but if you must, then consider using a function node & node.send()

As for actual nested arrays - they can be many forms...

  • [ [1,2,3,4,5] , ['A','B','C','D','E'] ]
  • or [ [1,'A','B','C','D','E'], [2,'A','B','C','D','E'], [3,'A','B','C','D','E'], [4,'A','B','C','D','E'], [5,'A','B','C','D','E'] ]
  • or [ [1,'A'] , [1,'B'] , [1,'C'] , [1,'D'] , [1,'E'] , [2,'A'] , [2,'B'] , [2,'C'] , [2,'D'] , [2,'E'] , [etc] [etc] ]
  • or .... what_ever_combination_of_outer_and_inner_arrays_you_can_think_of ...

Back to your question on looping nested arrays...

Since you provided 2 CSV strings (not a nested array) - I will show you how you can use "nested loop" in a function node...

var csv1 = 'A, B, C, D, E'; //this could come from a msg property like payload
var csv2 = '1, 2, 3, 4, 5'; //this could come from a msg property like payload2
var arr1 = csv1.split(", ");
var arr2 = csv2.split(", ");

//nested loop...
for(let i = 0; i < arr1.length; i++) {
 let a = arr1[i];
 for(let j = 0; j < arr2.length; j++) { 
  let b = arr2[j];
  node.send( { payload : `http://${a}/${b}` } );
 }
}
[{"id":"7ad49895.7e8df8","type":"inject","z":"b59e78a1.da9bc8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":950,"y":740,"wires":[["3bbf74d2.9b4d5c"]]},{"id":"3bbf74d2.9b4d5c","type":"function","z":"b59e78a1.da9bc8","name":"","func":"var csv1 = 'A, B, C, D, E'; //this could come from a msg property like payload\nvar csv2 = '1, 2, 3, 4, 5'; //this could come from a msg property like payload2\nvar arr1 = csv1.split(\", \");\nvar arr2 = csv2.split(\", \");\n\n//nested loop...\nfor(let i = 0; i < arr1.length; i++) {\n let a = arr1[i];\n for(let j = 0; j < arr2.length; j++) { \n  let b = arr2[j];\n  node.send( { payload : `http://${a}/${b}` } );\n }\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1110,"y":740,"wires":[["e33f6b5b.8644b8"]]},{"id":"e33f6b5b.8644b8","type":"debug","z":"b59e78a1.da9bc8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1270,"y":740,"wires":[]}]

Lastly

if what you REALLY want (because you dont say) is how to do nested loop using that specific contrib node...

My first answer is - DONT - you mostly likely dont need to as I demonstrated in my first solution using split nodes.

My second answer is - you'll probably need to ask on the github issues pages for that node as its not used a lot (as far as I know) (I dont use it and have never needed to - but thats me)

Thanks a lot for you feedback.

First of all I'm sorry for my late answer. I'm also sorry for the misunderstanding, my english is quite poor adn sometimes it's not easy to do a good explanation ...

I also want to thank you for feedback which is exactly what I looking for.

To be honest I haven't seen the array loop node don't make part of the native node-red nodes.

Thanks a lot.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.