Wednesday, January 31, 2024

Avoiding nested loops and conditions in Power Automate

What's the issue with nesting? 

Nested loops or conditions make your flow progressively more difficult to read and understand. And quite often they are unnecessary. In the case of loops (Apply to each), Power Automate is quite trigger happy and immediately encloses new actions in an Apply to each loop when you access an element of an array. And in the case of conditions, you often only need actions in one branch - but the second (empty) branch still takes up screen real estate. Also important, Power Automate has a nesting limit of 8 levels, not that I expect many of us to run into this limitation. Last but  not least, Apply to each loops are painfully slow, especially when variables are written inside the loop. But that's a topic for another post. 

What are your options?

For nested "Apply to each" loops: 

  • Replacing actions inside your Apply to each loop with Filter and/or Select actions. 
  • Only need to access the first element in the array? The function first() is a good option (although with some pitfalls...)
  •  Doing complex things inside your loop? Have you considered encapsulating it in its own child flow?
For nested conditions:
  • Consider using an if() expression instead of a condition
  • Use the Terminate action to remove some of the nesting levels, especially while checking for halting conditions ("Does X contain a value? If not -> exit flow")
  • Have you considered using a Switch action instead of a nested condition?
  • Have you tried adding multiple condition rows to your condition?
Let's quickly look at some of these options.

Filter and Select actions

These are extremely useful and efficient actions to handle arrays. In fact, they are so efficient that they often can be completed in a 1/100th of the time it takes to accomplish the same thing with an Apply to each loop. I encourage you to really try and master these two actions! A good place to learn them is on DamoBird365's Youtube videos, e.g. this one. A great introduction to Select by Alireza Aliabadi you can finde here.

first()

Let's say your variable called names contains three names: ["Joe", "Bill", "Max"].
first(variables('names') will of course return Joe. So couldn't you just use first() in all cases where an Apply to each loop is unnecessarily created? You could, yes, just be aware that first(), when used on an empty array, will return null, which maybe be incompatible with subsequent actions in your flow. 

Loading a single Dataverse row without first()

You may have noticed that eventhough your primarily name column may only contain unique entries, trying to load a single entry using such a name column will always return an array (with one or zero rows in it). That means every time you'd like to access data in that row you'd have to use first()? There are better solutions!
a) Load the row based on the unique GUID, using the action "Get a Row by ID". This is guaranteed to return only a single row. If necessary load this GUID using a separate "List Rows" (Dataverse). In the subsequent actions, always refer to the output of "Get a Row by ID" - no first() required!

Loading a single Sharepoint list row without first()?

The approach is similar to the method for Dataverse. "Get item" will try an load a Sharepoint list row using the column "ID". It's also a hidden column, that's created automatically. So you may have to first use "Get items" with a Filter query to extract the hidden ID value. Check out the example below. Now you can use dynamic content to access the values inside of your target row!



Conclusion

Let me know, if there's a specific approach that you'd like to hear more about. 

Sunday, January 28, 2024

Welcome to "Professional Power Automate"!

 Hi everyone and welcome to the "Professional Power Automate" blog. When I was learning Power Automate, I often ran into the issue that there are hardly and blogs on more advanced topics, like "what are best practices to create robust flows" or "what should I consider when deciding a complex system of child flows?". Writing blog posts is also a great way for me to collect my findings and bring them into a more concise form. In that regard, writing is also part of my own learning journey. I also would love this to be a community effort in the sense that we all have different approaches and practices. So, your comment is always welcome. However, all comments are moderated to avoid spam and off-topic discussions. Please be patient, if it takes a couple of days for your comment to pass moderation :).

What this blog is for

  • Designing complex flow systems
  • Best practices
  • Advanced discussions
  • Hardening flows
  • Premium license aspects and workarounds
  • Creating more efficient and fast flows
  • Helper tools that make designing and developing flows easier
  • Dataverse tips
  • Speeding up your workflow

What this blog is NOT about

  • off-topic discussions, i.e. anything outside of the Power Automate and Dataverse
  • not primarily a support blog!
  • Eventhough the name may suggest it: Power Automate for Desktop is considered off-topic (at least for now)

About me

My name is John Flury and I've been working in IT here in Zurich, Switzerland for the last 17 years, after studying computer science at the University of Zurich. My programming background is in Java and C/C++, but I was never a full-time developer. As an IT manager, my focus have been mainly business processes. As such, it's no surprise that Power Automate caught my attention. Since about 2 years I teach Power Automate beginner classes and also work as freelance Power Platform consultant and developer. In my freetime I enjoy being a "Maker", creating interactive installations for kids and build things in and around our house, using Arduino, 3D-Printing, wood and metal. 

Insanely fast synchronization from a Dataverse table to a SharePoint List

Don’t be fooled: this challenge is deceptively hard — at least if you want to make it fast, efficient, and robust .  Feature specs Your sour...