Power Apps  

Powerful Looping Patterns in Power Apps - ForAll()

ForAll() is one of the most powerful — and most misunderstood — functions in Power Apps.
It enables looping, bulk operations, and batch processing, but misuse can cause performance issues, delegation warnings, and unpredictable behavior.

This article explains how ForAll() actually works, when to use it, when not to use it.

1. What is ForAll()?

ForAll() iterates over each record in a table and evaluates a formula for each one.

ForAll(
    Table,
    Formula
)

  • Table → collection, data source, or result of Filter()

  • Formula → evaluated once per record

2. Understanding How ForAll() Executes

  • Runs in parallel, not sequentially

  • Order of execution is not guaranteed

  • You cannot rely on variable values changing per iteration

3. Bulk Patch to SharePoint List

Scenario

Update multiple list items selected in a gallery.

ForAll(
    Gallery1.SelectedItems,
    Patch(
        Feedback,
        ThisRecord,
        {
            Status: "Approved",
            ApprovedBy: User().Email,
            ApprovedOn: Now()
        }
    )
)

4. Creating New Records in Loop

Scenario

Create task items for each selected user.

ForAll(
    colUsers,
    Patch(
        Tasks,
        Defaults(Tasks),
        {
            Title: UserName,
            AssignedTo: UserEmail
        }
    )
)

5. ForAll + Collect Pattern (In-Memory Processing)

Scenario

Build a transformed dataset before saving.

ClearCollect(
    colPreparedData,
    ForAll(
        SourceCollection,
        {
            Title: ThisRecord.Name,
            IsActive: ThisRecord.Status = "Active"
        }
    )
)

6. Updating Multiple Lists Safely

Scenario

Patch two lists per record.

ForAll(
    colItems,
    With(
        {
            updatedItem: Patch(
                Orders,
                ThisRecord,
                { Status: "Processed" }
            )
        },
        Patch(
            AuditLog,
            Defaults(AuditLog),
            {
                OrderId: updatedItem.ID,
                Action: "Processed"
            }
        )
    )
)

7. Conditional Processing Inside ForAll

Scenario

Only update items matching a condition.

ForAll(
    colItems,
    If(
        Quantity > 0,
        Patch(
            Inventory,
            ThisRecord,
            { InStock: true }
        )
    )
)

8. Delegation Rules with ForAll

Delegation Warning

ForAll() itself is not delegable.

ClearCollect(
    colPending,
    Filter(LargeList, Status = "Pending")
);

ForAll(
    colPending,
    Patch(...)
)

9. ForAll with Attachments

Scenario

Copy attachments from one list to another.

ForAll(
    AttachmentControl.Attachments,
    Patch(
        TargetList,
        Defaults(TargetList),
        {
            Title: ThisRecord.Name,
            Attachments: ThisRecord.Value
        }
    )
)

10. Error Handling in ForAll()

ForAll(
    colItems,
    IfError(
        Patch(TargetList, ThisRecord, { Status: "Done" }),
        Collect(
            colErrors,
            {
                ItemId: ThisRecord.ID,
                Error: "Patch failed"
            }
        )
    )
)

Conclusion

ForAll() is powerful — but it should be the last step in your pipeline, not the first.

When NOT to use ForAll()

  • Large data sources (>2k rows)

  • High-volume transactional systems

  • Sequential logic required