Loop step
Run steps once for each item in a list.
The Loop step runs the steps nested under it once for each item in a list. Use it to send each order, line or product to another system one at a time.
Set it up
| In the app | data field | What it does |
|---|---|---|
| Variable to iterate | variable_to_iterate | The name of the variable holding the list, like orders. An array, or an object (one pass per key). |
| Index variable | index_variable | Optional. Gets the position (or key) on each pass, like i. |
| Data variable | data_variable | Gets the current item on each pass, like order. |
Drag the steps that should run for each item under the Loop.
Declare the index and data variables before the loop, for example $.i = 0; $.order = null; in a Script step, or as job variables, so they're filled in on each pass.
How it behaves
- It needs a real list. A variable holding JSON text (like a response
bodyor$.default) fails withvariable must be an array or an object, so parse it in a Script step first. A variable that isn't set at all just skips the loop. - An empty list does nothing. The nested steps simply don't run, so you don't need an If Condition just to guard against an empty list. Add one if you want to do something else when there's nothing to process.
- There's a limit of 10,000 passes per job, across all Loops in the job. Past that, the job fails with
loop iteration limit exceeded: at most 10000 loop iterations per job. - Steps inside a Loop run again on a retry. If the job fails halfway through and is retried, the loop starts again from the first item. Make the calls inside it safe to repeat, for example with an "update if it exists" call or the other system's de-duplication key.
For very large lists, it's often better to send them in one call (or one file) than one call per item. See Transform Data and File.
Example 1: Post an adjustment for each open order
Trigger: Scheduled.
-
REST Request: Get open orders, Response variable
orders_res, Fail on bad response code on. -
Script: Read the order list
$.orders = JSON.parse($.orders_res.body) || []; $.i = 0; $.order = null; -
If Condition: If there are orders, Condition
$.orders.length > 0. This one is optional, because a Loop over an empty list does nothing. -
Loop: For each order, Variable to iterate
orders, Index variablei, Data variableorder. Nested under it:- Script: Shape the line:
$.adjust_body = JSON.stringify({ sku: $.order.sku, quantity: -$.order.quantity }); - API Request: Post the adjustment, Body
{{ adjust_body }}.
- Script: Shape the line:
Example 2: Send each sale line to another system
Trigger: System Hook, Create Sale.
-
Script: Read the sale
var sale = JSON.parse($.default); $.sale = sale; $.lines = sale.lines || []; $.line_index = 0; $.line = null; -
If Condition: If the sale has lines (optional, as above).
-
Loop: For each line, Variable to iterate
lines, Index variableline_index, Data variableline. Nested under it:- Script: Read the line:
$.line_body = JSON.stringify({ sale_id: $.sale.id, item_id: $.line.item_id, quantity: $.line.quantity }); - REST Request: Send the line, Body
{{ line_body }}.
- Script: Read the line:
Tips
- Use Liquid inside the loop too.
{{ line.item_id }}works in the nested steps' fields. - Filter before you loop. A Transform Data step can drop the items you don't need, so the loop does less.
Updated about 23 hours ago
