The Switch() in Power Automate is a little interesting to me, in theory its a lookup, which any Excel user will tell you is probably the most fundamental function of Excel (v/xlookup of course). And as Power Automate is aimed at citizen developers who most likely used Excel before, its strange its not used very often.
I see nested If()'s all the time, but rarely a Switch, and I think its for a few reasons:
- Templates & Copilot prodomently use If()
- Most documentation/blogs/guides use If()
- Switch() can only do one logic (each branch can only check same thing)
- It doesnt scale well
- In the designer the horizontal expansion is not user friendly
I think its probably the last two that have the the biggest impact.
It doesn't scale well
Continually having to add branches is not the best way to scale. This often requires duplication of code, and worst of all a deployment.
In the designer the horizontal expansion is not user friendly
Working on a big Switch() is simply awful, scrolling sideways is goes against all the muscle memory of moving vertically. And because the rest of the flow is vertical you have to do a lot of scrolling to got back on path. The new UI is definitely an improvement, especially with the zoom, but that bad first impression will take a lot to get over.
Luckily there is a better way to do a Switch(), which scales infinitely and is a lot easier to build with.
The Super Switch() does 2 important things, keeps everything vertical, and best of all, outsources the branches from Power Automate (well kind of).
There are 3 levels to the Super Switch:
- Variables
- HTTP
- Delegated
Variables
The way the Super Switch works is following the Excel way, we move the branches to a table (either SharePoint or Dataverse). We use the filter query to get the record we like and then it returns our configs/variables.
We then pass those configs into our actions and we get our branching logic without branches.
As you may have guessed, because we are only have variables to use, it won't be able to do actions, well actually it can, and that's when it gets a little more complex.
2. HTTP
So if we are limited to just variables then lets use a action that is more flexible, and you guessed it that's the HTTP actions. We are now limited to Microsoft Graph endpoints but that covers a lot of scenarios (you could use the http action and do a lot more, but be careful how you store any credentials to auth).
Our look up table can pass the end points we want, so we are no longer scoped to same actions per branch, just same connections.
We use the replace() function to update the config response (good news is if the placeholder for the input isn't there it is simply ignored), so we are not limited to same inputs per branch.
Example
In the below example we are doing a get item and a create item, they use some inputs that are the same, but the get has dynamic url, and the create a dynamic body. As you can see the replace() is used on both of the dynamic inputs, the create doesn't have a '{id}' so the replace() function just returns the raw input, just as we want. And as the the get body is blank, it does the same.
site
json(outputs('Get_items_2')?['body/value'][0]?['json']?['site'])
type
json(outputs('Get_items_2')?['body/value'][0]?['json']?['type'])
url
replace(
json(outputs('Get_items_2')?['body/value'][0]?['json']?['url'])
,
'{id}'
,
triggerBody()['text_1']
)
body
replace(
replace(
json(outputs('Get_items_2')?['body/value'][0]?['json']?['body'])
,
'{title}'
,
triggerBody()['text_2']
)
,
'{description}'
,
triggerBody()['text_2']
)
We can also be creative, with branches for all connections or run afters, and use coalesce to get the action that responds.
3. Delegated
So you need full flexibility, with totally different actions in each logic branch, well there is a way and that's to delegate the actions to Child Flows 😎
Our List has all the conditions we want to check and sends back the childflow to call.
Though these child flows are a little different, as we can't dynamically call childflows.
As in if I had the below,
I should be able to peak the code,
and paste it in dynamically with the right schema:
But for some reason it throws error when try and save.
But luckily there is a workaround, a HTTP flow trigger (but don't worry no SPN needed for auth as we are being creative).
Securing the HTTP Child flow
We simply replace the Manual trigger for our childflow and add the 'When a HTTP request is received'.
We add a trigger condition that checks for a apiKey header, it's not the best way to do it (as the apiKey is stored in plain text inside the flow definition), but its secure enough for what we need.
Child Flow
We then add in the exact same json schema we used for the childflows and then save to get the trigger url.
In our config list we store the flows trigger url and the apiKey, along again with the same info from the HTTP version (type, url, body).
Parent Flow
The parent flow uses the HTTP action, just like we did with HTTP Super Switch, but now we can call any combination of connections.
We can add new branches by adding to the config list and creating a new 'Child' flow.
Although the normal Switch covers most use cases, having a selection of Super Switches is always useful, and this creative approach can be leveraged for other solutions too.
As always copy of a demo solution can be found in my GitHUb repo here
If you would like to get notified every new blog (I also do a few in the Power Platform Community), subscribe below
Cool tip to have in the tool belt !!