This post is part of a technical series to help Salesforce Admins automate business processes using Flow.
Loops are one of the more powerful things you can do in Salesforce Flow. The open up all sorts of possibilities but they're also a bit intimidating. That's totally understandable! The other kinds of Salesforce automation (like Process Builder) don't even include loops. In this post we'll provide a full guide to loops in Salesforce Flow, including an example using Flow loops to perform efficient record updates.
Here's the agenda:
- What is a loop?
- What's a collection?
- The Flow loop structure by example
- A (weird) word of caution
What is a loop?
You actually use loops in real life all the time. You just might not realize it.
Suppose Amanda, a sales manager, sends you a spreadsheet with a list of accounts and she says, "Hey, could you assign these to Sarah?" Chances are you immediately know what to do. Maybe you fire up data loader or maybe you just quickly go to each account in Salesforce and change the owner.
The thing is, you're way smarter than a computer. If you wanted to tell a computer to do the same thing, you'd have to dumb it down to be really specific. You'd say something like, "Ok computer, start with the first account you see and change the owner to Sarah. Now look at the next account and change that one to Sarah. Now look at the next account...." until you're done.
That's a lot of repetition; there's got to be an easier way even for a dumb computer! What if you could just say "Ok, computer, start with the first account, change the owner to Sarah. Now repeat that for each of the accounts in the list." Not bad. You don't have to say too much and it's simple enough even for a dumb computer to handle it.
There are lots and lots of tasks that follow this same pattern. Data cleanup for a list of contacts, updating various fields for a list of Leads, etc, etc.
Well, good news! That's pretty much a loop in Flow. It really just comes down "do some stuff for each thing in this list". In fact you'll see those words "for each" in the Flow Builder when you create a loop.
But first, what's a collection?
Flow calls lists of things "collections". It's a complicated name for a simple concept. Whenever you see the word "collection" in the Flow Builder, just think "list".
Remember, a loop is all about doing some stuff for each thing in a list. We call this "looping over" or "looping through" a collection. So naturally, loops in Flow are pretty tied to collections. In fact, you can't use a loop if you don't have a collection.
Where do you get a collection? The vast majority of the time, the collections you'll be dealing with are lists of records that come from a Get Record element. (You can also store lists of things in variables but that's something for another post.)
Here's a quick look at a Get Records element that finds all Contacts where their email address contains "example.com". If you're following along at home, you can create a new Flow with the type "Autolaunched Flow (No Trigger)" and then create this same action yourself.
The important thing here is that you're telling Get Records to get "All records" . When you do this, the Get Records element will retrieve a collection (aka "list") of contacts, not just one. Note that the API Name for this element is "Get_Example_Contacts". We'll use that later in our loop.
The Flow loop structure by example
Every loop in Flow has the same basic structure. You need to provide the following things:
- A collection (list!) of things to loop over
- A set of steps you want to do for each thing in the collection
- A set of steps you want to do after the last thing in the collection
Let's run through a full example of using a loop in Flow. We're also going to address an issue that a lot of people have when first using Flow loops. Changing records inside the loop doesn't always do what you think. We'll show you how to make sure your record updates actually happen with loops.
Set the loop collection
Let's create a new loop element and set the collection. Make sure you're using Auto-Layout in Flow Builder. Click the + under the Get Records element you created previously, scroll down and select "Loop".
Again we set the Label and API Name. Make a note that we're calling it "Each_Contact". As you can see, when you click into the "Collection Variable" , you'll see "Contacts from Get_Example_Contacts" . Flow calls this a "Record Collection Variable". Again, a complicated name for a pretty simple idea. This is just the list of contacts that you got based on the criteria you set in the "Get_Example_Contacts" element.
If you click "Done" on this screen and you're using Auto-Layout in the Flow Builder, you'll see this:
Hey, look at that! It's setting you up for the other two parts of your loop: what you do for each record in the collection and what you do after the last record.
Do something for each record
The cool part about loops is you can do any set of steps you want to "inside" the loop. In most cases, though, you want to do something to each record in the collection. That's why you're using a loop in the first place. You do this by accessing the "Current Item" from your loop.
You can think of all the steps inside your "for each" section as a mini Flow unto itself that runs for every record in the collection. It can contain any elements a Flow can: Assignments, Decisions and even other loops.
Let's continue this contrived example and change each contact's description inside the "For Each" section. Click the "+" just below "For Each" and choose "Assignment. Here's what you'll see:
The Label and API Name are familiar by now, so that's easy. We know that we want to set the Description field for each Contact record. When you click the "Variable" field , you'll see "Current Item from Loop Each_Co..." pop up . It's annoying that the name is cut off, but this is what allows us to access the current record in our loop. It's the secret to making the change for each Contact. Select it, then select Description (the field we want to change).
Here's what it looks like all put together with description being set to "Just an example contact"
And here's what our loop looks like now:
There's one more step that's necessary to make sure we can do record updates. Flow treats the "Current Item" in a special way. If you change the Current Item in the "For Each" part of the loop, it doesn't actually change that record in the loop's collection. If we want to update these records later, we have to put each record into a new collection to update them.
That requires just a little bit of fancy footwork. First, we need to create a new collection variable to contain the modified contacts. Click "New Resource" in the "Toolbox" on the left of the Flow Builder, select "Variable" for the Resource Type and enter in the following:
Now that we've got that, we just need to add our Current Item to that list. You do that with an Assignment. Click the + as usual and select Assignment.
We're telling Flow to Add  the Current Item  to the "Modified_Contacts" collection .
Here's what it looks like now that we're all done with the for each part.
Now, we want to actually update these modified contact records to make sure our changes get saved.
Do something after (the) last record
Ok, so we've gone through and modified each Contact but we haven't actually updated them yet. If we stopped here, nothing would be saved. What we really want to do update all the modified Contacts after we've processed the last record in the loop.
Flow provides the Update Records element to do this job. All we need to do is run it after we're done with our loop. So, follow the line down from "After Last" and click the +, then click "Update Records".
In this case, we want to Update all the Contacts in our Modified_Contacts collection, not the Current Item (we already changed each of those). So we tell Flow to use field values from a record collection  and then set that collection to be the whole collection of Modified_Contacts .
The full loop
It took some work, but it reads pretty clearly. Here are the steps:
- "Get Example Contacts" - Get a collection (list!) of contacts using a Get Records element
- "Each Contact' - Set up a loop to make a change for each Contact record
- "Set Description - Set the description field for each Contact using an Assignment element
- "Add to Modified Contacts" - Add the modified Contact record to the Modfied_Contacts collection so we can update them all at once after we've processed the last record in the loop
- "Update Contacts" - Update the entire collection of Modified_Contacts using an Update Records element after the last item in the list
You can run this by saving it and clicking "Debug" in the Flow Builder. If you do run it, it will really update any Contacts with an example.com email address you may have. Be careful if you're doing this in production!
A (weird) word of caution
With great power comes great responsibility. One thing you should try to avoid is putting any Get Records, Create Records, Delete Records or Update Records steps inside the "For Each" part of your loop. This is a good way to run into trouble with Salesforce's limits.
This is often shortened to "no pink elements inside a loop". All of Flow's data elements are pink and so if you see one inside the "for each" part of the loop, you should try to get rid of it.
Typically you want to do things like the example in this post: assign values to fields, add them to another collection, then update the whole collection of records all at once. This is frequently referred to as "bulkification" and is a bit of an advanced topic. Bulkification is a very weird word but it basically means "try to get/create/update/delete stuff all at once instead of one-by-one".
Where to go from here
Loops are something we do every day in our work without even really thinking about it. They're also one of the things that makes Flow much more powerful than Process Builder. Plus, they're not as complicated as they first seem. Don't be afraid to use them.
Here are some times to consider using loops:
- Batch processes that need to make a change each item in a list of records
- Loops that contain Decision elements are a great way to make conditional updates to records in a list (just make sure to use assign-each-update-all-after-last pattern)
Next, take a look at our resource on updating records in Salesforce Flow. Happy Flowing.