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_pathFull path for nested loops
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.

Nested Loops

Loops can be nested for multi-level data:

For Each: orders

  For Each: loop.current.items

    Process item

Nested Index Paths

For nested loops:

loop.index_path = "0.2.1"  // 1st order, 3rd item, 2nd sub-item

Accessing Parent Loop

In nested loops, access parent data:

{{ loop.parent.current.order_id }}

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

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
  • Use calculations for aggregations

Testing

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