Last Updated: 05-27-2021
Update
There is now a 3rd option for accomplishing this: Looping by Zapier!
Looping by Zapier was built with some of the issues in mind that could crop up using a Code Step, like not inputting Line Item data with null values properly. It works similarly to the Code Step below behind the scenes, but has some nice bells and whistles, like Line Item support and more.
You can read about it here: https://zapier.com/help/create/other-functions/loop-your-zap-actions
You can add it to your Zaps by searching for Looping by Zapier as the app when adding a new Step.
Intro
Sometimes we want to run an Action or set of Actions more than once in our Zaps. Today I’d like to show you how we can do that if the number of times we want to run that action is variable.
In the world of programming, we can create loops that run a bit of code once for each of a set of values. We can do this in a Zap as well. If you don’t know how to code, that’s ok! It’s my hope that with this guide, you won’t need to know how to take advantage of this.
Let’s say I have a Trigger that provides a Line Item (array) or comma separated text containing email addresses and first names and I’d like to send a customized email to each one of them:
If we tried to map the email addresses into the “To:” field, that line item would be converted into comma separated text, so a single email would be sent to all the recipients, but they would all see each other’s email address. Worse, the names would be a comma separated text list in the greeting of our email.
What we really want is for the Zap to run the email Step once for each email and name so that each recipient gets a separate email.
The ideas that we’ll explore would also apply to circumstances where we want to add multiple contacts or leads to a CRM, create multiple documents, send multiple text messages, and more. If an Action supports line items, that support can be used many times for a similar effect, like adding multiple rows to a spreadsheet in Google Sheet’s “Create Spreadsheet Row(s)”. Many actions don’t support line items, and that’s where these techniques come in handy.
There are two ways to create a loop to repeat one or more actions for different values:
Option 1: Use Google Sheets as an intermediary
This method involves setting up two Zaps and a Google Sheet:
Google Sheet:
- Create a header for each value that you want to repeat in one or more actions
Zap 1:
- Your original Trigger
- Actions before you want to loop
- If the values aren’t already in Line Item format, use the Formatter App’s Utility Action: Line Itemizer transform to convert the values into line items (unless they already are)
- Action: Google Sheets: Create Spreadsheet Row(s) (Mapping each value you want to send to into the various fields in the sheet - 1 or more rows will be created for the line items. You can mix and match single values and line item values. Line item values each be used once per row. Single values will be repeated for each row - think values like name or email address)
Zap 2 (runs once for each row created by the line items in Zap 1):
- Trigger: Google Sheets: New Spreadsheet Row
- Action: One or more Action(s) that you want to repeat
In summary, Zap 1 “sets up” the loop, and Zap 2 runs the looped actions with the values posted to each row of the sheet.
Option 2: Use a “Code by Zapier” Action (sometimes referred to as a “Code Step”) to “fork” a Zap
Option 1 works well enough, but it is more difficult to manage over time than a single Zap because we have two Zaps and a spreadsheet to keep track of. Let’s take a look at how using a small amount of reusable code, we can keep things in a single Zap.
Most Steps in Zapier give an output of one JSON object wrapped in an array. When using any value from that object in a subsequent Step, that Step will run once. If we use a Code Step to output multiple JSON objects of the same structure wrapped in an array, the later Steps will run once for each object in the array instead, creating the loop we’re looking for.
A common example of this is that you're already familiar with is a Zap Trigger. Triggers that ask an app for new data to Trigger on get 0 or more objects in an array returned, and then the Zap runs once for each object.
When we’re testing this in the Zap editor, similar to how we can only use one Sample from a Trigger at a time, we’ll only see the first object, and the Zap Steps will only run once when testing. When running live, they will run once per object (set of values).
First, let’s take a look at the values we’re going to input into the Code Step. They could be Line Items like this:
![](https://uploads-us-west-2.insided.com/zapier-ca/attachment/28515ba9-ed0a-452e-8e9a-3c2898ee93c7.png)
Or comma separated text like this:
![](https://uploads-us-west-2.insided.com/zapier-ca/attachment/1ee59f48-6ac7-44e0-8b20-ac5d6b83a18e.png)
When we map the values into the Code Step, they will be converted to comma separated text if they’re not already, so the both examples above will work the same way.
When you’re adding the Code Step to your Zap, you’ll specifically want to use “Run Javascript” if you’re using the code I’ve included here.
When we map those values into the Code Step, we’ll want to types names for each set of values on the left of the Input Data fields (green highlight) and map the actual series of values on the right (purple):
![](https://uploads-us-west-2.insided.com/zapier-ca/attachment/1d21cd76-dae5-4dd0-be4c-93376c8abef0.png)
You can paste the following Code into the Code Field as-is. You won’t need to modify it all, regardless of the names and quantities of different values you’re using. It will detect the names of your values automatically from the Input Data field (green highlight). Here’s the code to copy and paste:
/* Add as many Input Data fields as you like above as comma seperated text or mapped line items (will be
converted to comma seperated text). This code will find each Input Data field and output an array of
objects with the same structure that can be used to "Fork" the Zap.
Example: https://cdn.zappy.app/9de81901f3750ef26bcbbd0737b0937b.png */
// get Input Data field names
let keys = Object.keys(inputData)
let data = .];
// loop through each Input Data field
for (let key of keys) {
// split the contents of each Input Data field on the commas into an array
let li = inputData/key].split(",");
for (let i=0; i<li.length; i++) {
if (typeof datali] === "undefined") datapi] = {};
datali] key] = li;i];
// add a record number (in case we want to break the fork/loop with a Filter)
dataii].recordNumber = i+1;
}
}
// preview the whole data structure in the output
console.log(data);
// output the data
output = data;
When you test the Code Step, you’ll see something like this:
![](https://uploads-us-west-2.insided.com/zapier-ca/attachment/5ff89f72-9733-4bc2-97f5-2536f6873f75.png)
As you can see, the the values that we get back (in red) match the names of the Input Data fields and additionally have a “recordNumber” value, but we only get the first set of values to test with, just like when we’re testing a Trigger. By mapping any of those values into a field in the next Action, when the Zap runs live, that Action will be repeated for each set of values.
In order to give you a better preview of what will actually happen with the live Zap, I’ve set the code to output a “log” that shows all the sets of value (highlighted in green). You can see how the first record is listed there, too (in red).
Here’s what it looks like if we map those values into an Email by Zapier action:
![](https://uploads-us-west-2.insided.com/zapier-ca/attachment/b0ce6a0d-03d0-4042-b6b2-276ccb211495.png)
Once the Zap starts looping, every Action from that point on will loop and run multiple times. If we need to break the loop, we can do that by:
- Where we want the loop to stop, add a Filter that only continues the Zap if the “Record Number” value exactly matches to “1”.
- The Filter will loop, too, but will only pass once for the first set of values in the loop, meaning that we’ll be back to not looping for the Actions after that.
If we don’t need to run any Actions just once after the ones that we want to loop, we don’t need to worry about breaking the loop.
And that should do it! With these workflows, Zap Actions that can only send a single set of values to an app can send multiple sets of values instead!
If you have any questions about this, I’d be happy to field them here!
Please note
We aren't always able to help with Code questions via Zapier Support because not everyone on the Support Team is familiar with Javascript and Python, and supporting custom code is technically outside of our scope of support. A great place to ask if we can't support you directly is here in our community or on Stack Overflow by tagging your question "Zapier": https://stackoverflow.com/questions/tagged/zapier