By working with Azure Logic Apps, data can be processed very quickly and conveniently. Sometimes small details are a challenge, like function names or correct syntax. This is especially true if you don't work with logic apps all the time. In addition to our existing tips here in the blog, we have some other useful functions from various scenarios that will make your work with Logic Apps easier.
If you are interested, we have already collected a number of tips in our blog in category Logic Apps. So, here are some more general tips for your flows.
Access items in a Loop
To work with an item in a For each loop action, use...
item()
...or, if there are multiple properties in an item, we can use the property name. Keep in mind that the expressions are case sensitive.
item()?['id']
To access items from another For each loop, use the name of the action.
items('foreachitem')?['id']
Rename actions
By the way, we find it very useful to always rename actions to make them easier to access in expressions. Standardize and use Camel case or all lowercase and remove spaces or use similar naming conventions. It´s nicer to use "initEmails", than "Initialize_variable", etc.
Please always rename your actions for better readability, at least for productive flows (and forgive us for mixing it up here in the demos in the article).
Sort items
Some data operations are missing an "order by" option. Well, when we have all items, we can sort ourselves. Here, we have an array of 3 email addresses that are unsorted.
We can sort as here:
sort(variables('emails'))
The variable or output then is sorted.
Using variables in For Each Loops
We can also use variables and e.g. the sort expression in For each loops, to ensure that items are sorted. But, since loops by default run asynchronously, we have to ensure that they are processed in synchronous mode...
When we adapt the flow as here with a loop action, and a HTML table that represents the result...
...we see that the emails2 array is not sorted. This is because the loop runs parallel.
We have to change the behavior of the foreachitem loop in the Settings of the action:
The Concurrency Control must be set to On, and the Degree of Parallelism must be set to 1.
Note: If we turn off parallelism, the loop takes much longer. This is a compromise for certain use cases. Ultimately, you have to weigh up what the goal is and the amount of data to be processed. For example, the For each loop concurrent iterations is between 1 and 20. The default run duration of a Logic App is 90 days. See the current limits at Looping, concurrency, and debatching limits. It is also important to choose between standard logic apps that run in a single-tenant environment and offer better performance and isolation including VNET integration compared to the multi-tenant consumption model.
The flow´s Workflow settings allow to set security and runtime settings, as here.
In our sample (with very little data) we now get the desired result. The names are sorted.
So, keep in mind the by default loops are running parallel! Change this setting if you work with variables in loops!
Get the real username of a guest user from Entra
When Microsoft Entra stores a guest user, the UserPrincipalName is generated out of the email address, and the primary domain name is added.
The email address guest_user1@gmail.com is stored as guest_user1_gmail.com#EXT#@mycompany.onmicrosoft.com.
While this is useful to have unique user names in Azure AD, ah, Entra, this is not useful if you want to do anything with that user, like sending an email to the user. In most cases, you want to get the "real" email address. The challenge here is, that a simple replace() function will not work in all cases. If we would remove the #EXT# part, and replace the underscore (_) with an at symbol (@), alle underscores would be replaced. In our sample, this would lead to an incorrect email address guest@user1@gmail.com. Sol, this is a some effort to create a working expression (without the need to work with loops or other voluminous constructs), and we have solved that for your.
You can do so with the following expression. Here, we assume, the guest user email address is stored in a variable named email.
concat(substring(substring(variables('email'), 0, indexOf(variables('email'), '#EXT#')), 0, lastIndexOf(substring(variables('email'), 0, indexOf(variables('email'), '#EXT#')), '_')),'@', substring(substring(variables('email'), 0, indexOf(variables('email'), '#EXT#')), add(lastIndexOf(substring(variables('email'), 0, indexOf(variables('email'), '#EXT#')), '_'), 1)))
It took some attempts to construct a good working expression, but this does the job. We get the email address out of the UserPrincipalName. In our sample, we get guest_user1@gmail.com, whatever domain might be added in Entra. This expression also works well in asynchronous loop actions since there are no variables used. This expression is long, but easy to use in other actions. Mission accomplished.
We hope these tips help you develop your Azure Logic apps smoothly!