# Loop Action

Loop Action allows you to execute another action as many times as the amount of items in your array. \
It is useful when you have an array of items and need to make additional request for each item of the array or when you simply need to send a bunch of items to the API.

## Action configuration

Loop Action takes the `{{data}}` variable passed from the previous step and, if this variable is an array, executes the specified action as many times as the amount of items in the array.

<figure><img src="/files/LxcBiYMWUVen91fkR2cP" alt=""><figcaption></figcaption></figure>

You can configure the following *settings* for this action:

**a. Return an array for iteration** - if you need to iterate some custom value, you can provide it instead of the previous step result. \
For example, iterate over `{{ui.table.value}}` - an array of table rows.

**b. Action to execute in loop** - the main setting which determines which action will be executed in a loop.

**c.** **Max iterations number** - the maximum amount of iterations to be performed. When the iteration value is not set or set to 0, the number of iterations will be automatically set to infinity.\
Configuring this number can prevent the Loop Action from running into the API rate limits (in UI Bakery, the limit is 3 requests per second).

**d. Execute in chunks of** - allows you run the iterations in chunks. The actions in chunks will be executed in parallel. If you don't want chunking, set the number to 1.

**e. Delay between chunks** - allows you to configure the delay between the chunks. By default, it is set to 300 ms.

**f. Transform result** - a custom JavaScript function can be provided to modify the result of the action calls. Available variables: `{{data}}` and `{{error}}` - an array of results and errors.

### Parallel and sequential action execution

By default, the Loop Action tries to execute all iterations in parallel. This means that all iterations will start almost simultaneously. The resulting array will still respect the order: the result of the first run will be under the 0 index, the second run under the 1 index, etc.

But you can also select the **Execute sequentially** checkbox to execute all iterations sequentially. The second iteration will only be run after the first one is completed, either successfully or with an error.

<figure><img src="/files/QTbaieg0fJQ7t09D7Wuh" alt=""><figcaption></figcaption></figure>

Parallel execution is faster than sequential, in a way, but both of them are better suited for different cases.\
For example, if you do multiple database requests that don’t depend on each other, it is recommended to run them *in parallel*. \
But if you are inserting items and need to respect the insert order, then *sequential execution* is a better choice.

### Input & Output

* **Input** - expects an array of items to iterate through.
* **Output** - `{{data}}` - an array of execution results, `{{error}}` - an array of execution errors.

## Use cases

Among some of the most common use cases of the Loop Action are:

* **Bulk creating/updating users** - collecting all new/edited users in an array and then calling the `POST/PUT` methods for every new item.
* **Loading additional data** - loading your users and then making additional requests for each user to load more information about them.
* **Sending multiple notifications** - locating users that need to be notified about something and then sending them Slack notifications.

Let's review a couple of examples:point\_down:&#x20;

### Sending a Slack message to each loaded user

Here, we'll load users via an API request and then send a bunch of Slack messages to these loaded users.

1. Start by creating a new action that will consist of **two steps** (we'll name it *requestUsers*):
   1. For the *first step*, add an HTTP Request action step, select the GET method, and provide the URL to load a list of users.
   2. For the *second* step, add a Loop Action step and click **+ Create action** in the *Action to execute in loop* dropdown.
2. For this new action, select your *Slack* data source and specify the **Message body**, for example:

<pre class="language-json"><code class="lang-json"><strong>{
</strong>  text: "Hello" + {{data.firstName}},
}
</code></pre>

{% hint style="info" %}
You can use the `{{data}}` variable to reference a single item of the initial users array.
{% endhint %}

3. Now, run the *requestUsers* action and check the *Result* tab of the Loop Action.

You'll see that it has the same amount of responses from the Slack action as the amount of users in the array (in our case, it's 25). \
The *Logs* tab of the *sendMessage* action will also have the same number of action executions.

{% @arcade/embed flowId="uvE8lXeXeSATSgxIZgBA" url="<https://app.arcade.software/share/uvE8lXeXeSATSgxIZgBA>" %}

### Sending a Slack message to each user selected in the table

1. First, add a new column to the table displaying your list of users - select *enabled* (from the Field name dropdown) and the *Boolean* type.\
   This column will be used to filter out only the selected rows.
2. Next, add a **Loop Action** and reference the Table component's value with the filter function in the *Return an array for iteration* field, for example:

```javascript
return {{ui.usersTable5.value}}.filter(item => item.enabled);
```

3. Create a new *sendMessage* to be executed as the Loop one - select your *Slack* data source and specify the **Message body**, for example:

```json
{
  text: "Hello" + {{data.name}},
}
```

4. Now, run your Loop Action and check the *Result* tab.

You'll see that it has the same amount of responses from the Slack action as the number of rows selected in the table (in our case it's 5). \
The *Logs* tab of the *sendMessage* action will also have the same number of action executions.

{% @arcade/embed flowId="YmMnh2Pi5lN4Y0TXQWWp" url="<https://app.arcade.software/share/YmMnh2Pi5lN4Y0TXQWWp>" %}

## Troubleshooting & debugging

If a Loop Action fails, its result will be set as *undefined* in the `{{data}}` results array and an error will be added to the `{{error}}` array. You can use the action's *Logs* tab to debug the failed executions.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.uibakery.io/reference/working-with-actions/loop-action.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
