Welcome to the second installment of PM on Call. If you missed my last post, go ahead and check it out here where I introduce the PM on Call concept and provide more background.
Another scenario that I have encountered a few times from both internal and external customers is understanding how the Do Until loop action works. There seems to be a common misconception about how it works, so let’s demystify how it works in this post. I will also add that what I am about to cover is applicable to both Azure Logic Apps and Flow, but will be using Microsoft Flow for these examples.
The scenario that we have is we want to perform a specific set of actions until some condition has been met. The two common scenarios are:
- I would like to perform this step ‘x’ times. So more specifically, I want a loop to run for 5 times.
- I would like to continue to perform a set of steps until a data attribute is a specific value. For example, I want to execute a loop until a status value in a SharePoint list item is equal to “Complete”.
For this blog post we will focus on the SharePoint scenario. In this case, we are managing a task list. When we create the task we want to ensure that the task owner gets reminders until they complete the task. But, once they complete a task, we don’t want to send them reminders any more. It is really annoying to get nag reminders for tasks that you have already completed.
When creating a Do Until loop, there are three core concepts that we need to account for:
- Our own criteria condition is satisfied: “Status Value is equal to Complete”
- Count: Our loop executes 60 times
- Timeout: Our loop runs for 20 minutes
Note: The default timeout is 60 minutes, but I have reduced for the purpose of this blog post. Use a value that makes sense for you.
Most importantly, we need to understand that the first of these thresholds to be met will exit the loop.
- When people build a solution that will send nag emails until the SharePoint Status Value is equal to Complete it often times looks like the following. We will soon discover why this design won’t meet our requirements.
- Let’s understand why this won’t work and create a new record inside our SharePoint List. We will set our Status to Not Started.
- Our flow will start and we can see we are approximately 41 seconds into the flow run.
- Let’s head back to SharePoint and update our Status to Complete.
- So the expectation is, upon the next iteration of our loop, after our 5 minute delay shape, our condition will be met and we will stop sending nag emails. But, as we can see based upon the run history of the flow, it was our timeout of 20 minutes that caused the flow to stop.
- In addition, our user received 4 nag emails instead of just 1. That is not cool!
This brings us to our next misconception about Do Until and flow in general. When we look at our condition of Status Value is equal to Complete, our Status Value represents its value at a point in time. Which means, flow is only aware of this value at the time it was retrieved, which in this case, was when we received the trigger event. In the meantime, the value in SharePoint may have changed, but flow doesn’t know about it. Remember that flow is stateless, in respect to external system values.
- In order for flow to know what is the current value of Status is, we need to go ahead and retrieve it again. One way we can accomplish this is to include variables where we can store the state of our Status value and continue to update it as we iterate through our loop. Below our trigger, we will add an Initialize variable action and then assign Value to Status Value (from SharePoint).
- Next, instead of using our Status Value directly in our Do Until condition, we will use our new variable which we called TaskStatus.
- Lastly, we will now update our TaskStatus variable with the most recent value in our SharePoint list item, So the next time we enter the Do Until loop, we have an up-to-date value we can use to evaluate our condition.
Note: Make sure you get the latest Status Value from the Get Item outputs and not from the trigger (remember, that value hasn’t changed since flow received it).
- For completeness, here is what our flow now looks like in its entirety.
- Let’s now go and create a new record in SharePoint and see how our flow performs.
- We can now see our new flow running
- We now need to go update our SharePoint list item and set its Status to Complete and before our Delay action completes.
If we now look at our completed flow run, we will see that it ran the way we intended it to:
- We captured our initial value for our SharePoint list item
- It was set to Not Started, so we entered the Do Until loop
- One email was sent to our task owner, reminding them to complete their task
- In the mean time, we updated our SharePoint item so that when we perform the Get item call we can retrieve the latest value.
- We then store this latest value in our TaskStatus variable.
- When we re-enter the loop, after the 5 minute delay, our condition is evaluated, but it is satisfied so we exit our loop.
So hopefully this post clears up how to use Do Until within Microsoft Flow (and Azure Logic Apps). The most important thing to remember is when a value is received via a trigger, it can change in the source system, but Microsoft Flow won’t know about it unless it is subsequently retrieved.
Also, worth noting is that I have used a very short duration for my Delay condition. More realistically, you may delay for a day or even a week. My value was chosen so that I could write this post in one sitting and not over the course of days or weeks.