FormWork FormWork

For Each Loops

Iterate over collections in workflows.

The For Each step lets you iterate over collections, running workflow steps for each item. This is essential for processing repeatable groups, data table rows, or any array data.

When to Use For Each

Common use cases:

  • Process each item in an order
  • Validate each row in a repeater
  • Update multiple related entries
  • Aggregate calculations across items

Creating a For Each Loop

Basic Setup

  1. Add a For Each step
  2. Configure the collection to iterate
  3. Add steps inside the loop
  4. Connect the loop exit

Visual Structure

For Each (items)

  [Loop Body]
    Step A → Step B

[Loop Exit] → Next Step

Collection Types

Repeater Field Instances

Iterate over repeating group entries:

Collection: entry:current.answers.order_items

Each iteration has access to:

  • Instance ID
  • All field values in that instance

Data Table Rows

Iterate over data table results:

Collection: data_table:products[category="active"]

Each iteration provides:

  • Row ID
  • All column values

Array Values

Iterate over multiselect or array fields:

Collection: entry:current.answers.selected_categories

Each iteration provides:

  • Array index
  • Current value

Calculation Results

Iterate over computed arrays:

Collection: workflow:get_items.outputs.result

Accessing Loop Data

Current Item

Inside the loop, access the current item:

{{ loop.current }}
{{ loop.current.name }}
{{ loop.current.quantity }}

Loop Metadata

VariableDescription
loop.indexCurrent index (0-based)
loop.index_pathCurrent loop index path
loop.item_idUnique ID for current item
loop.currentThe current item data

For Repeater Items

When iterating repeater instances:

loop.item_id = instance ID (e.g., "abc123")
loop.current = { field_values }

Loop Body Steps

Running Steps

Steps inside the loop run for each item:

For Each: items

  Calculate: item_total = loop.current.price * loop.current.qty

  Update: items[{{ loop.item_id }}].total = item_total

Accessing Previous Steps

Within the loop, reference other loop step outputs:

{{ workflow:calc_item.outputs.result }}

This gets the result from the same iteration.

Loop Limits

For Each steps cannot be placed inside another For Each loop. If you need to process multi-level data, split the work into separate workflows or flatten the collection before the loop runs.

Aggregating Results

Collect Results

Each loop iteration can produce outputs:

For Each: items

  Calculate: item_total

[Loop outputs collected]

Access All Results

After the loop:

workflow:foreach.outputs.iter_outputs
workflow:foreach.outputs.iter_outputs[0].item_total

Aggregate in Next Step

Calculate totals after loop:

SUM(workflow:foreach.outputs.iter_outputs|pluck:"item_total")

Example: Order Processing

Scenario

Process each item in an order:

  1. Calculate line total
  2. Update item record
  3. Sum order total

Workflow

Trigger: Form Submitted

For Each: order_items

  Calculate: line_total = price * quantity

  Update: items[{{ loop.item_id }}].line_total = line_total

Calculate: order_total = SUM(items|pluck:"line_total")

Update: total = order_total

Example: Validation

Scenario

Validate each employee record in a repeater.

Workflow

For Each: employees

  Condition: loop.current.email is_empty
    ├─ True: Set: items[{{ loop.item_id }}].valid = false
    └─ False: Set: items[{{ loop.item_id }}].valid = true

Condition: ANY items|pluck:"valid" = false
  └─ True: Update entry.status = "needs_review"

Best Practices

Limit Iterations

For very large collections:

  • Consider pagination
  • Process in batches
  • Use server-side processing for 100+ items
  • Keep loops single-level; nested For Each steps are not supported

Error Handling

Handle errors within loops:

For Each: items

  API Call
    ├─ Success: Continue
    └─ Error: Log error, continue to next item

Performance

  • Minimize API calls inside loops
  • Batch operations when possible
  • Keep loop body steps focused on the smallest useful unit of work
  • Use calculations for aggregations

Testing

  • Test with empty collections
  • Test with single item
  • Test with many items
  • Check edge cases