RAP Logo

counter-loop

Help flow looping the specified times for batch processing with iteration tracking.

counter-loop Block

The counter-loop block helps flow looping the specified times.

Overview

The counter-loop block is designed to execute repeated operations with a counter, making it ideal for batch processing with iteration tracking. It provides a controlled way to loop through a sequence a specified number of times.

Configuration Options

Loop Configuration

  • Count: The number of times to loop (can be a fixed number or dynamic value)
  • Start Value: The initial value for the counter (default: 0)
  • Increment: How much to increment the counter each iteration (default: 1)
  • Counter Property: The message property to store the current counter value

Loop Behavior

  • Loop Direction: Forward (incrementing) or backward (decrementing)
  • Loop Condition: When to stop the loop
  • Output Behavior: What to send on each iteration and when complete

How It Works

The counter-loop block:

  1. Initializes: Sets up the counter with the starting value
  2. Iterates: Executes the loop the specified number of times
  3. Increments: Updates the counter value on each iteration
  4. Outputs: Sends messages with the current counter value
  5. Completes: Sends a completion message when the loop finishes

Basic Loop Example

Count: 5
Start Value: 1
Increment: 1

Output:
Iteration 1: counter = 1
Iteration 2: counter = 2
Iteration 3: counter = 3
Iteration 4: counter = 4
Iteration 5: counter = 5
Complete: loop finished

Use Cases

Batch Processing

Process a fixed number of items:

input → counter-loop (count: 10) → process item → output

Data Generation

Generate a sequence of data:

counter-loop (count: 100) → generate data → store

API Calls

Make multiple API calls:

counter-loop (count: 5) → http request → process response

File Processing

Process multiple files:

counter-loop (count: fileCount) → read file → process → save

Common Patterns

Simple Counter Loop

// Configuration
Count: 10
Start Value: 0
Increment: 1
Counter Property: msg.payload.iteration

// Output messages
{ payload: { iteration: 0, data: "..." } }
{ payload: { iteration: 1, data: "..." } }
// ... continues until iteration 9
{ payload: { iteration: 10, complete: true } }

Reverse Loop

// Configuration
Count: 5
Start Value: 5
Increment: -1
Counter Property: msg.payload.countdown

// Output messages
{ payload: { countdown: 5 } }
{ payload: { countdown: 4 } }
{ payload: { countdown: 3 } }
{ payload: { countdown: 2 } }
{ payload: { countdown: 1 } }
{ payload: { countdown: 0, complete: true } }

Dynamic Count

// Configuration
Count: msg.payload.totalItems
Start Value: 0
Increment: 1
Counter Property: msg.payload.currentIndex

// Use with dynamic input
{ payload: { totalItems: 7 } } → loop 7 times
{ payload: { totalItems: 3 } } → loop 3 times

Advanced Features

Conditional Looping

Combine with other blocks for conditional behavior:

input → switch (check condition) → counter-loop → processing

Nested Loops

Use multiple counter-loop blocks for nested iterations:

outer-loop → inner-loop → process → next outer iteration

Loop State Management

Maintain state across loop iterations:

// Use flow context to store state
flow.set("loopState", {
  processed: 0,
  errors: 0,
  results: [],
});

Tips

  • Choose Appropriate Counts: Set reasonable loop counts to avoid infinite loops
  • Handle Errors: Implement error handling for failed iterations
  • Use Meaningful Properties: Store counter values in descriptive message properties
  • Consider Performance: Be mindful of loop performance with large counts
  • Test Edge Cases: Verify behavior with count = 0, count = 1, and large counts
  • Monitor Resources: Watch for memory usage with large loop counts

Common Issues

Infinite Loops

Avoid setting count to 0 or negative values:

// BAD: This could cause issues
Count: 0;

// GOOD: Use meaningful counts
Count: Math.max(1, msg.payload.itemCount);

Memory Issues

Be careful with large loop counts:

// BAD: Very large count
Count: 1000000;

// GOOD: Process in batches
Count: 100;
// Then use another loop for the next batch

State Management

Properly manage state across iterations:

// BAD: Not clearing state
flow.set("tempData", newData);

// GOOD: Clear state when complete
if (msg.payload.complete) {
  flow.set("tempData", null);
}