logo_smallAxellero.io

Loop

Iterate over arrays, objects, or execute a specified number of times with full context access.

The Loop node provides powerful iteration capabilities for workflows, allowing you to process arrays, objects, or execute a block of nodes a specific number of times. Each iteration has access to the current item and index through the workflow context.

┌───────────────────────────────────────────────────────────┐
│                      LOOP ITERATION                       │
├───────────────────────────────────────────────────────────┤
│                                                           │
│    ┌─────────┐     ┌───────────────────────────┐          │
│    │  START  │────▶│      Loop Node            │          │
│    └─────────┘     │  • Array: [1,2,3]         │          │
│                    │  • Index: 0,1,2...        │          │
│                    └─────┬────────────────┬────┘          │
│                          │                │               │
│                        (LOOP)         (DEFAULT)           │
│                          │                │               │
│                          ▼                ▼               │
│                    ┌─────────┐      ┌─────────┐           │
│                    │ Process │      │  AFTER  │           │
│                    │ Current │      │  LOOP   │           │
│                    │  Item   │      │ COMPLETE│           │
│                    └─────────┘      └─────────┘           │
│                         │                │                │
│                         │                │                │
│                         └────────────────┘                │
│                        (back to loop)                     │
│                                                           │
└───────────────────────────────────────────────────────────┘

Configuration

PropertyValue
Workflow TypesWorkflow

Output Configuration

Loop Type

Configure how the loop operates:

FieldTypeOptionsDefaultDescription
TypeSelectFORFORIteration method (WHILE support coming soon)

Value Input

Define what to iterate over or how many times to iterate:

FieldTypeDefaultDescription
ValueAny-Array/object to iterate or number for count-based loops

Index Management

FieldTypeDefaultDescription
IndexInteger0Current iteration index (automatically managed)

Loop Outputs

Loop nodes provide context data that can be accessed in connected nodes:

OutputTypeDescription
itemAnyCurrent iteration item (for arrays/objects)
indexIntegerCurrent iteration index (0-based)

Accessing Loop Outputs:

// Access current item
{{ctx.nodes.loopNode.outputs.item}}

// Access current index  
{{ctx.nodes.loopNode.outputs.index}}

// Use in conditions
{{ctx.nodes.loopNode.outputs.index < 5}}

FOR Loop Implementation

Array Iteration

Process each element in an array:

Configuration:

  • Type: FOR
  • Value: ["apple", "banana", "cherry"] or {{ctx.nodes.dataSource.outputs.fruits}}

Iteration Behavior:

// Iteration 0: item = "apple",  index = 0
// Iteration 1: item = "banana", index = 1  
// Iteration 2: item = "cherry", index = 2

Example Use Case:

// Process each user in a list
Value: {{ctx.nodes.userApi.outputs.users}}

// In loop body, access current user:
{{ctx.nodes.loopNode.outputs.item.name}}
{{ctx.nodes.loopNode.outputs.item.email}}

Object Iteration

Process key-value pairs in an object:

Configuration:

  • Type: FOR
  • Value: {"name": "John", "age": 30, "city": "NYC"}

Iteration Behavior:

// Iteration 0: item = {"name": "John"}, index = 0
// Iteration 1: item = {"age": 30}, index = 1
// Iteration 2: item = {"city": "NYC"}, index = 2

Accessing Object Data:

// Get the key
{{Object.keys(ctx.nodes.loopNode.outputs.item)[0]}}

// Get the value
{{Object.values(ctx.nodes.loopNode.outputs.item)[0]}}

Count-Based Iteration

Execute a specific number of times:

Configuration:

  • Type: FOR
  • Value: 5 or {{ctx.nodes.config.outputs.repeatCount}}

Iteration Behavior:

// Iteration 0: item = undefined, index = 0
// Iteration 1: item = undefined, index = 1
// Iteration 2: item = undefined, index = 2
// Iteration 3: item = undefined, index = 3
// Iteration 4: item = undefined, index = 4

String Character Iteration

Iterate over each character in a string:

Configuration:

  • Type: FOR
  • Value: "hello"

Iteration Behavior:

// Iteration 0: item = "h", index = 0
// Iteration 1: item = "e", index = 1
// Iteration 2: item = "l", index = 2
// Iteration 3: item = "l", index = 3
// Iteration 4: item = "o", index = 4

Loop Execution Flow

Iteration Process

When a Loop node executes:

  1. Initialize: Index starts at 0, value is evaluated
  2. Check Condition: Determine if more iterations are needed
  3. Execute Body: If condition true, execute LOOP-connected nodes
  4. Increment: Index automatically increments after iteration
  5. Repeat: Return to step 2 until condition becomes false
  6. Exit: Execute DEFAULT-connected nodes when loop completes

Context Management

Each iteration maintains:

  • Current Index: Available as {{ctx.nodes.loopNode.outputs.index}}
  • Current Item: Available as {{ctx.nodes.loopNode.outputs.item}}
  • Iteration State: Automatically managed by the execution engine
  • Separate Context: Each iteration has isolated input/output context

Advanced Loop Patterns

Conditional Processing

Use loop context in Branch nodes for conditional logic:

// Process only even-indexed items
{{ctx.nodes.loopNode.outputs.index % 2 === 0}}

// Process items meeting criteria
{{ctx.nodes.loopNode.outputs.item.status === "active"}}

// Skip first item
{{ctx.nodes.loopNode.outputs.index > 0}}

Data Transformation

Transform each item in a collection:

// Example: Convert array of names to email addresses
// Loop Value: ["john", "jane", "bob"]
// In loop body:
const name = ctx.nodes.loopNode.outputs.item;
const email = `${name}@company.com`;
return email;

Batch Processing

Process items in batches using index:

// Process every 10th item
{{ctx.nodes.loopNode.outputs.index % 10 === 0}}

// Create batches
const batchSize = 5;
const currentBatch = Math.floor(ctx.nodes.loopNode.outputs.index / batchSize);

Accumulation Patterns

Build results across iterations:

// Collect results (in a non-loop node after completion)
const results = [];
// Results are typically collected in external storage or variables
// accessed after loop completion via DEFAULT connection

Loop Controls and Exit Conditions

Early Exit with Exception

Use Exception nodes within loops for early termination:

// Condition to exit loop early
{{ctx.nodes.loopNode.outputs.item.error !== null}}

// Connect to Exception node to terminate workflow
// or handle error condition

Index-Based Exit

Control loop execution based on index:

// Limit to first 10 iterations
{{ctx.nodes.loopNode.outputs.index >= 10}}

// Process until specific condition
{{ctx.nodes.loopNode.outputs.index >= ctx.vars.maxIterations}}

Integration with Other Nodes

With API Calls

Process each item through an API:

// Loop over user IDs, make API call for each
// Loop Value: [1, 2, 3, 4, 5]
// API URL: https://api.example.com/users/{{ctx.nodes.loopNode.outputs.item}}

With Conditional Logic

Use Branch nodes for complex iteration logic:

// Different processing based on item type
{{ctx.nodes.loopNode.outputs.item.type === "premium"}}

// Route to different processing paths
{{ctx.nodes.loopNode.outputs.item.category}}

With Data Storage

Store iteration results:

// Build arrays/objects across iterations
// Use workflow variables to accumulate data
// Access final results via DEFAULT connection after loop completion

Best Practices

Performance Optimization

  • Limit Iterations: Avoid extremely large loops that could impact performance
  • Efficient Processing: Keep loop body processing lightweight
  • Batch Operations: Consider batch processing for database operations
  • Memory Management: Be mindful of memory usage with large datasets

Error Handling

  • Validation: Validate loop value before iteration begins
  • Error Recovery: Handle errors gracefully within loop body
  • Exception Handling: Use Exception nodes for critical failures
  • Logging: Log iteration progress for debugging

Design Patterns

  • Single Responsibility: Keep loop body focused on one task
  • Reusable Logic: Design loop bodies that can be reused
  • Clear Naming: Use descriptive names for loop nodes and outputs
  • Documentation: Document complex loop logic for maintainability

Data Type Considerations

  • Array Validation: Ensure value is actually an array when expected
  • Object Structure: Validate object structure for consistent iteration
  • Type Checking: Handle mixed data types appropriately
  • Null Safety: Check for null/undefined values

Troubleshooting

Common Issues

ProblemSymptomsSolution
Infinite LoopWorkflow never completesCheck loop exit conditions and value type
No IterationsLoop body never executesVerify value is non-empty array/object or positive number
Context Access ErrorCannot access item/indexCheck context expression syntax
Connection IssuesWrong nodes executingVerify LOOP vs DEFAULT connections

Debugging Techniques

  1. Test with Small Data: Start with small arrays/low counts
  2. Check Loop Value: Verify the value evaluates to expected data type
  3. Validate Connections: Ensure LOOP and DEFAULT connections are correct
  4. Monitor Context: Check that item/index outputs are accessible
  5. Review Execution Flow: Trace through iteration logic step by step

Performance Issues

  1. Large Datasets: Consider pagination or batch processing
  2. Complex Loop Bodies: Simplify processing logic
  3. Nested Loops: Avoid deeply nested loop structures
  4. Resource Usage: Monitor memory and CPU usage

Examples

User Processing Workflow

// Loop Configuration
Type: FOR
Value: {{ctx.nodes.userApi.outputs.users}}

// In loop body - Update user status
URL: https://api.example.com/users/{{ctx.nodes.loopNode.outputs.item.id}}
Method: PUT
Body: {
  "status": "processed",
  "processedAt": "{{new Date().toISOString()}}",
  "batchId": "{{ctx.vars.batchId}}"
}

Data Transformation Loop

// Loop Configuration  
Type: FOR
Value: {{ctx.nodes.rawData.outputs.records}}

// Transform each record
const record = ctx.nodes.loopNode.outputs.item;
return {
  id: record.id,
  name: record.fullName?.trim(),
  email: record.emailAddress?.toLowerCase(),
  createdAt: new Date(record.timestamp).toISOString(),
  index: ctx.nodes.loopNode.outputs.index
};

Conditional Processing Loop

// Loop Configuration
Type: FOR 
Value: {{ctx.nodes.orders.outputs.data}}

// Branch condition - only process paid orders
{{ctx.nodes.loopNode.outputs.item.status === "paid"}}

// In processing branch
const order = ctx.nodes.loopNode.outputs.item;
return {
  orderId: order.id,
  amount: order.total,
  processedIndex: ctx.nodes.loopNode.outputs.index
};

Batch Processing with Index Control

// Loop Configuration
Type: FOR
Value: 100  // Process 100 items

// Branch condition - create batches of 10
{{ctx.nodes.loopNode.outputs.index % 10 === 0}}

// In batch processing branch
const batchNumber = Math.floor(ctx.nodes.loopNode.outputs.index / 10);
const itemsToProcess = ctx.vars.allItems.slice(
  ctx.nodes.loopNode.outputs.index, 
  ctx.nodes.loopNode.outputs.index + 10
);