PageSourceSearch

https://embedded-workflow-builder.netlify.app/assets/js/cacacfc4.73ffe6aa.js

js embedded-workflow-builder.netlify.app collected 2026-10-03 10:45:56 UTC 8,504 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkembedded_workflow_builder_docs=self.webpackChunkembedded_workflow_builder_docs||[]).push([["8306"],{11802(e,r,o){o.r(r),o.d(r,{metadata:()=>n,default:()=>h,frontMatter:()=>i,contentTitle:()=>l,toc:()=>c,assets:()=>a});var n=JSON.parse('{"id":"looping","title":"Looping","description":"The loop step allows you to iterate over an array of items or records","source":"@site/docs/looping.md","sourceDirName":".","slug":"/looping","permalink":"/looping","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Looping","description":"The loop step allows you to iterate over an array of items or records"},"sidebar":"docs","previous":{"title":"Branching","permalink":"/branching"},"next":{"title":"Triggering Workflows","permalink":"/triggering"}}'),t=o(74848),s=o(28453);let i={title:"Looping",description:"The loop step allows you to iterate over an array of items or records"},l,a={},c=[{value:"Looping over arrays of records",id:"looping-over-arrays-of-records",level:2},{value:"Looping a certain number of times",id:"looping-a-certain-number-of-times",level:2},{value:"Return values of loops",id:"return-values-of-loops",level:2}];function d(e){let r={a:"a",code:"code",h2:"h2",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.p,{children:"For many Workflows, it's useful to be able to loop over an array of items or to loop a certain number of times.\nIf your Workflow processes files on an SFTP server, for example, you might want to loop over an array of files on the server.\nIf your Workflow sends alerts to users, you might want to loop over an array of users."}),"\n",(0,t.jsxs)(r.p,{children:["The ",(0,t.jsx)(r.a,{href:"/connectors/loop",children:"loop"})," connector allows you to loop over each item in an array, or you can loop a predetermined number of times.\nAfter adding a ",(0,t.jsx)(r.strong,{children:"loop"})," step to your Workflow, you can then add steps within the loop that will execute repeatedly."]}),"\n",(0,t.jsx)(r.h2,{id:"looping-over-arrays-of-records",children:"Looping over arrays of records"}),"\n",(0,t.jsx)(r.p,{children:"Imagine you have a step that returns an array of records:"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-json",metastring:"title=\"Result of 'List Contacts' step\"",children:'[\n  { "first": "John", "last": "Doe", "country": "US" },\n  { "first": "Lisa", "last": "Nguyen", "country": "AUS" },\n  { "first": "Sarah", "last": "Smith", "country": "GB" }\n]\n'})}
1),"\n",(0,t.jsxs)(r.p,{children:["A loop step can then be configured to loop for each record by referencing the ",(0,t.jsx)(r.code,{children:"results"})," of the ",(0,t.jsx)(r.strong,{children:"List Contacts"})," step:"]}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.img,{alt:"Loop step reference results",src:o(98163).A+"",width:"1155",height:"655"})}),"\n",(0,t.jsx)(r.p,{children:"If you're familiar with JavaScript programming, this is similar to running"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-js",children:"for (const record of records) {\n  doThing(record);\n}\n"})}),"\n",(0,t.jsx)(r.p,{children:"The loop step provides a few properties to steps within the loop:"}),"\n",(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsxs)(r.li,{children:[(0,t.jsx)(r.code,{children:"currentItem"})," represents the item in the array that is currently being processed"]}),"\n",(0,t.jsxs)(r.li,{children:[(0,t.jsx)(r.code,{children:"index"})," represents the ",(0,t.jsx)(r.a,{href:"https://en.wikipedia.org/wiki/Zero-based_numbering",children:"zero-indexed"})," index of the current value."]}),"\n",(0,t.jsxs)(r.li,{children:[(0,t.jsx)(r.code,{children:"isFirst"})," is ",(0,t.jsx)(r.code,{children:"true"})," if the current item is the first item in the array, and ",(0,t.jsx)(r.code,{children:"false"})," otherwise."]}),"\n",(0,t.jsxs)(r.li,{children:[(0,t.jsx)(r.code,{children:"isLast"})," is ",(0,t.jsx)(r.code,{children:"true"})," if the current item is the last item in the array, and ",(0,t.jsx)(r.code,{children:"false"})," otherwise."]}),"\n"]}),"\n",(0,t.jsxs)(r.p,{children:["Using the example above, during the second loop cycle ",(0,t.jsx)(r.code,{children:"currentItem"})," would equal ",(0,t.jsx)(r.code,{children:'{ "first": "Lisa", "last": "Nguyen", "country": "AUS" }'})," and ",(0,t.jsx)(r.code,{children:"index"})," would equal ",(0,t.jsx)(r.code,{children:"1"}),"."]}),"\n",(0,t.jsxs)(r.p,{children:["If you would like to use values of the current item, you can reference things like ",(0,t.jsx)(r.code,{children:"currentItem.country"})," in the example above as an input for a step."]}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.img,{alt:"Current item reference",src:o(26910).A+"",width:"1064",height:"965"})}),"\n",(0,t.jsxs)(r.p,{children:["If you use a ",(0,t.jsx)(r.a,{href:"/custom-code",children:"code step"})," within a loop, you can reference ",(0,t.jsx)(r.code,{children:"currentItem"})," and ",(0,t.jsx)(r.code,{children:"index"})," like this:"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-js",metastring:'title="Example code step referencing a loop\'s current item"',children:"module.exports = async (\n  { logger },\n  { loopOverContacts: { currentItem, index } },\n) => {\n  logger.info(\n    `User #${index + 1}: ${currentItem.first} ${currentItem.last} from ${currentItem.country}`,\n  );\n};\n"})}),"\n",(0,t.jsx)(r.h2,{id:"looping-a-certain-number-of-times",children:"Looping a certain number of times"}),"\n",(0,t.jsxs)(r.p,{children:["Sometimes you'll want to loop a set number of times.\nFor those situations, a ",(0,t.jsx)(r.a,{href:"/connectors/loop#loopntimes",children:"Repeat X Times"})," action can help."]}),"\n",(0,t.jsxs)(r.p,{children:["Programmatically, the ",(0,t.jsx)(r.strong,{children:"Repeat X Times"})," action is similar to a ",(0,t.jsx)(r.code,{children:"for"})," loop like this:"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-js",children:"for (let index = 0; index < SOME_NUMBER; index++) {\n  doThing(index);\n}\n"})}),"\n",(0,t.jsxs)(r.p,{children:["Like ",(0,t.jsx)(r.a,{href:"#looping-over-arrays-of-records",children:"looping over arrays"}),", ",(0,t.jsx)(r.strong,{children:"Repeat X Times"})," provides a ",(0,t.jsx)(r.code,{children:"currentItem"})," and ",(0,t.jsx)(r.code,{children:"index"}),", which both represent the same thing (a ",(0,t.jsx)(r.a,{href:"https://en.wikipedia.org/wiki/Zero-based_numbering",children:"zero-indexed"})," count of the current loop iteration).\nSo, the first loop iteration ",(0,t.jsx)(r.code,{children:"index"})," will be ",(0,t.jsx)(r.code,{children:"0"}),", the second iteration will have an ",(0,t.jsx)(r.code,{children:"index"})," of ",(0,t.jsx)(r.code,{children:"1"}),", etc."]}),"\n",(0,t.jsx)(r.h2,{id:"return-values-of-loops",children:"Return values of loops"}),"\n",(0,t.jsxs)(r.p,{children:["A loop will collect the results of the ",(0,t.jsx)(r.strong,{children:"last"})," step within the loop and will save those results as an array."]}),"\n",(0,t.jsx)(r.p,{children:"For example, if the last step of a loop returns a string like this:"}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-javascript",children:"module.exports = async(context, loopOverContacts: { currentItem }) =>
1 {\n    return {data: `Processed ${currentItem.first} from ${currentItem.country}`}\n}\n"})}),"\n",(0,t.jsxs)(r.p,{children:["Then the ",(0,t.jsx)(r.code,{children:"result"})," of the loop will yield:"]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-json",children:'["Processed John from US", "Processed Lisa from AUS", "Processed Sarah from GB"]\n'})})]})}function h(e={}){let{wrapper:r}={...(0,s.R)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},26910(e,r,o){o.d(r,{A:()=>n});let n=o.p+"assets/images/current-item-reference-8e44ab0e5cf93bbc9e5bb89e705de402.png"},98163(e,r,o){o.d(r,{A:()=>n});let n=o.p+"assets/images/loop-step-reference-results-53e93bfaad5a1683cb945a9213ea2a35.png"},28453(e,r,o){o.d(r,{R:()=>i,x:()=>l});var n=o(96540);let t={},s=n.createContext(t);function i(e){let r=n.useContext(s);return n.useMemo(function(){return"function"==typeof e?e(r):{...r,...e}},[r,e])}function l(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),n.createElement(s.Provider,{value:r},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.