Some checks failed
App Prod-Parity E2E Dispatch / dispatch (push) Failing after 10s
CD Storybook UI / build (push) Failing after 3m25s
CD Storybook UI / dispatch (push) Has been skipped
CD deploy main / website-changed-files (push) Successful in 18m8s
CI Agent Skills / changed-files-check (push) Successful in 18m9s
CI Create App E2E minimal / changed-files-check (push) Successful in 24s
CI Create App / changed-files-check (push) Successful in 26s
CI Docs / changed-files-check (push) Successful in 26s
CI Emails / changed-files-check (push) Successful in 28s
CI Example App Hello World / changed-files-check (push) Successful in 23s
CI Front / changed-files-check (push) Has been skipped
CI Example App Postcard / changed-files-check (push) Successful in 27s
CI UI / changed-files-check (push) Has been skipped
CI Utils Test / changed-files-check (push) Successful in 45s
CI Twenty Apps / discover (push) Successful in 1m3s
CD deploy main / deploy-main (push) Failing after 3s
CI Agent Skills / agent-skills-validate (push) Has been skipped
CI Create App / create-app-test (lint) (push) Has been skipped
CI Emails / emails-test (push) Has been skipped
CI Front / front-task (lingui:compile) (push) Has been skipped
CI Front / front-task (lint) (push) Has been skipped
CI Example App Postcard / example-app-postcard (push) Has been skipped
CI UI / ui-task (lint) (push) Has been skipped
CI UI / ui-task (pack-size) (push) Has been skipped
CI UI / ui-task (size) (push) Has been skipped
CI UI / ui-task (test) (push) Has been skipped
CI UI / ui-task (typecheck) (push) Has been skipped
CI Utils Test / utils-test (push) Has been skipped
CI Twenty Apps / ${{ matrix.app.name }} (push) Has been skipped
CI Emails / ci-emails-status-check (push) Successful in 2s
CI Example App Hello World / ci-example-app-hello-world-status-check (push) Successful in 2s
CI Example App Postcard / ci-example-app-postcard-status-check (push) Successful in 3s
CI UI / ui-sb-test (push) Has been skipped
CI Utils Test / ci-utils-test-status-check (push) Successful in 2s
CI Twenty Apps / ci-twenty-apps-status-check (push) Successful in 2s
CI UI / ci-ui-status-check (push) Successful in 2s
CI Desktop / desktop (push) Failing after 1m8s
Push docs to Crowdin / Push documentation to Crowdin (push) Failing after 55s
Push translations to Crowdin / Extract and upload translations (push) Failing after 5s
Push website translations to Crowdin / Extract and upload website translations (push) Failing after 5s
CI Create App / create-app-test (test) (push) Has been skipped
CI Create App / create-app-test (typecheck) (push) Has been skipped
CI Docs / docs-lint (push) Has been skipped
CI Example App Hello World / example-app-hello-world (push) Has been skipped
CI Front / front-task (lingui:extract) (push) Has been skipped
CI Front / front-task (test) (push) Has been skipped
CI Front / front-task (typecheck) (push) Has been skipped
CI UI / ui-sb-build (push) Failing after 1m32s
CI Twenty Apps / ${{ matrix.app.name }} (${{ matrix.server-source }}) (push) Has been skipped
CI Agent Skills / agent-skills-publish (push) Has been skipped
CI Create App / ci-create-app-status-check (push) Successful in 2s
CI Agent Skills / agent-skills-remote-source (push) Has been skipped
CI Create App E2E minimal / create-app-e2e-minimal (push) Has been cancelled
CI E2E Main / e2e-test (push) Has been cancelled
CI Front / front-sb-build (push) Has been cancelled
CI Front / front-build (push) Has been cancelled
CI Create App E2E minimal / ci-create-app-e2e-minimal-status-check (push) Has been cancelled
CI E2E Main / ci-e2e-main-status-check (push) Has been cancelled
CI E2E Main / notify-main-ci-failure (push) Has been cancelled
CI E2E Main / qa-scout-comment (push) Has been cancelled
CI Front / front-sb-test (push) Has been cancelled
CI Front / front-sb-screenshots (push) Has been cancelled
CI Front / ci-front-status-check (push) Has been cancelled
DPA Sub-Processor Sync / sync-subprocessors (push) Failing after 3s
AI Catalog Sync / sync-catalog (push) Failing after 2s
182 lines
5.7 KiB
Plaintext
182 lines
5.7 KiB
Plaintext
---
|
|
title: Use Iterator
|
|
description: Loop through arrays of records to perform actions on each item.
|
|
---
|
|
|
|
Iterator lets you loop through an array of records and perform actions on each one. It's essential for workflows that need to process multiple records returned by Search Records or received via webhooks.
|
|
|
|
|
|
## When to Use Iterator
|
|
|
|
| Scenario | Example |
|
|
|----------|---------|
|
|
| **Process search results** | Send email to each person found |
|
|
| **Handle webhook arrays** | Create records for each item in order |
|
|
| **Bulk updates** | Update multiple records with calculated values |
|
|
| **Notifications** | Alert multiple people about an event |
|
|
|
|
## Understanding Iterator
|
|
|
|
Iterator expects an **array** as input. It then:
|
|
1. Takes the first item from the array
|
|
2. Runs all actions inside the Iterator with that item
|
|
3. Moves to the next item
|
|
4. Repeats until all items are processed
|
|
|
|
### Selecting the array to loop over
|
|
|
|
Most array sources (Search Records, a webhook array field, a Bulk manual trigger) can be selected directly in the variable picker.
|
|
|
|
When a **Code** or **Logic Function** step returns a *top-level array*, its output appears in the variable picker as indexed entries (`0`, `1`, `2`, …). To loop over the array as a whole, select the **Whole list** option for that step — the Iterator then infers the shape of each item from the list automatically.
|
|
|
|
## Basic Setup
|
|
|
|
### Example: Email Everyone in Search Results
|
|
|
|
**Goal**: Find all contacts in a specific company and send each one a personalized email.
|
|
|
|
### Step 1: Search for Records
|
|
|
|
1. Add **Search Records** action
|
|
2. Object: **People**
|
|
3. Filter: Company equals "Acme Inc"
|
|
4. This returns an array of people
|
|
|
|
### Step 2: Check Results Exist
|
|
|
|
1. Add **Filter** action
|
|
2. Condition: `{{searchRecords.length}}` is greater than 0
|
|
3. This prevents Iterator errors on empty results
|
|
|
|
### Step 3: Add Iterator
|
|
|
|
1. Add **Iterator** action
|
|
2. Array input: Select `{{searchRecords}}`
|
|
3. This creates a loop
|
|
|
|
### Step 4: Add Actions Inside Iterator
|
|
|
|
Actions placed after Iterator run for each item:
|
|
|
|
1. Add **Send Email** action (inside Iterator)
|
|
2. To: `{{iterator.currentItem.email}}`
|
|
3. Subject: Hello `{{iterator.currentItem.firstName}}`!
|
|
4. Body: Personalized message using current item fields
|
|
|
|
### Result
|
|
|
|
If Search Records returns 5 people, the Iterator:
|
|
- Sends email to person 1
|
|
- Sends email to person 2
|
|
- ... continues for all 5
|
|
|
|
## Accessing Current Item Data
|
|
|
|
Inside Iterator, use `{{iterator.currentItem}}` to access the current record:
|
|
|
|
| Variable | Description |
|
|
|----------|-------------|
|
|
| `{{iterator.currentItem}}` | The entire current record object |
|
|
| `{{iterator.currentItem.id}}` | Record ID |
|
|
| `{{iterator.currentItem.email}}` | Email field |
|
|
| `{{iterator.currentItem.company.name}}` | Related company name |
|
|
| `{{iterator.index}}` | Current position in array (0-based) |
|
|
|
|
In the variable picker, you can either drill into a specific field of the current item, or pick **Use the whole item** to reference the entire current item (`{{iterator.currentItem}}`). Selecting the whole item is handy when you want to pass a full record straight into a downstream step rather than rebuilding it field by field.
|
|
|
|
## Common Patterns
|
|
|
|
### Update Multiple Records
|
|
|
|
**Goal**: Mark all overdue tasks as "Late"
|
|
|
|
```
|
|
1. Search Records (Tasks, Due Date < Today, Status ≠ Completed)
|
|
2. Filter (length > 0)
|
|
3. Iterator (searchRecords)
|
|
└── Update Record
|
|
- Object: Tasks
|
|
- Record: {{iterator.currentItem.id}}
|
|
- Status: Late
|
|
```
|
|
|
|
### Create Records from Array
|
|
|
|
**Goal**: Webhook receives order with multiple items, create a record for each
|
|
|
|
```
|
|
1. Webhook Trigger (receives items array)
|
|
2. Filter (items.length > 0)
|
|
3. Iterator (trigger.body.items)
|
|
└── Create Record
|
|
- Object: Order Items
|
|
- Name: {{iterator.currentItem.name}}
|
|
- Quantity: {{iterator.currentItem.qty}}
|
|
- Related Order: {{trigger.body.orderId}}
|
|
```
|
|
|
|
### Conditional Processing Inside Loop
|
|
|
|
**Goal**: Only send email to contacts with valid emails
|
|
|
|
```
|
|
1. Search Records (People)
|
|
2. Iterator (searchRecords)
|
|
└── Filter (currentItem.email is not empty)
|
|
└── Send Email
|
|
- To: {{iterator.currentItem.email}}
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### "Iterator expects an array"
|
|
|
|
**Cause**: You passed a single record instead of an array.
|
|
|
|
**Fix**: Make sure you're passing the result of Search Records or an array field, not a single record.
|
|
|
|
```
|
|
✅ Correct: {{searchRecords}}
|
|
❌ Wrong: {{searchRecords[0]}}
|
|
```
|
|
|
|
### Iterator Doesn't Run
|
|
|
|
**Cause**: The array is empty.
|
|
|
|
**Fix**: Add a Filter before Iterator to check array length:
|
|
```
|
|
Filter: {{searchRecords.length}} > 0
|
|
```
|
|
|
|
### Actions Run Too Many Times
|
|
|
|
**Cause**: Search Records returned more records than expected.
|
|
|
|
**Fix**:
|
|
- Add more specific filters to Search Records
|
|
- Set a limit on Search Records (max 200)
|
|
- Add Filter inside Iterator for additional conditions
|
|
|
|
## Performance Considerations
|
|
|
|
- **Credit usage**: Each iteration consumes credits for its actions
|
|
- **Time**: Large arrays take longer to process
|
|
- **Limits**: Consider batching very large operations
|
|
- **Rate limits**: External API calls may hit rate limits with many iterations
|
|
|
|
## Best Practices
|
|
|
|
1. **Always check array length** before Iterator to avoid errors
|
|
2. **Add filters inside loops** when not all items need processing
|
|
3. **Rename your Iterator step** to describe what it's looping through
|
|
4. **Test with small arrays** before processing large datasets
|
|
5. **Monitor workflow runs** to ensure iterations complete as expected
|
|
|
|
## Related
|
|
|
|
- [Workflow Actions](/user-guide/workflows/capabilities/workflow-actions)
|
|
- [How to Use Branches](/user-guide/workflows/capabilities/use-branches-in-workflows)
|
|
- [Workflows FAQ](/user-guide/workflows/how-tos/need-more-help/workflows-faq)
|
|
|