Day 4 — Expressions - the syntax that trips everyone up
This is the day Power Automate stops being drag-and-drop and starts being a skill.
Two ways to write an expression
| Written | Means | Gives back |
|---|---|---|
@expression | The whole value is the expression | The real type - a number stays a number |
text @{expression} text | Drop the value into a string | Text |
@triggerBody()?['Amount']
@{triggerBody()?['Amount']}
The amount is @{triggerBody()?['Amount']} rupees
@add(triggerBody()?['Amount'], 1000)
Total: @{add(triggerBody()?['Amount'], 1000)}
Each line is evaluated on its own. Edit them, add your own, press Run.
@.Building a sentence, a subject line, a file name - use
@{ } inside the text.Everything inside
@{ } becomes text, so @{add(1,2)} gives the string "3". Usually that is fine. When it is not, you will get a type error downstream and this is the reason.Single quotes. Never double.
concat('Hi ', 'there') is right. concat("Hi ", "there") is wrong, and the error you get does not say so clearly. The reason is that the whole flow is JSON, and JSON already uses double quotes - so they would end the string early.To put a real apostrophe inside, double it:
'it''s here'.
@concat('Data', ' ', 'Analytics')
@concat('it''s ', 'fine')
@toUpper('north')
@trim(' spaces ')
The question mark
?['Field'] instead of ['Field']. That one character is the difference between a flow that copes and a flow that dies at 3am.
@triggerBody()?['Name'] @triggerBody()?['Phone'] @triggerBody()['Phone']
The second line gives null and carries on. The third one fails, and it tells you which fields do exist - which is a useful message when you have mistyped a field name.
? turns a crash into a null you can handle with coalesce() or an if().Handling the null
@coalesce(triggerBody()?['Phone'], 'No phone given') @if(empty(triggerBody()?['Phone']), 'Missing', triggerBody()?['Phone']) @empty(triggerBody()?['Phone']) @empty(triggerBody()?['Name'])
coalesce() takes the first thing that is not empty. empty() is true for null, for an empty string, for an empty array and for an empty object - which makes it the safest test there is.
The string functions
@length(triggerBody()?['Name']) @toUpper(triggerBody()?['Name']) @split(triggerBody()?['Name'], ' ') @first(split(triggerBody()?['Name'], ' ')) @last(split(triggerBody()?['Name'], ' ')) @substring(triggerBody()?['Code'], 4, 4) @indexOf(triggerBody()?['Email'], '@@') @replace(triggerBody()?['Code'], '-', '/') @startsWith(triggerBody()?['Code'], 'ORD') @join(split(triggerBody()?['Name'], ' '), '_')
substring('ORD-2026-0042', 4, 4) gives 2026 - character 0 is the O.To search for a literal @ you type @@. A single @ starts an expression, so it has to be escaped. This bites everyone who splits an email address.
Capitalising a name properly
There is no "proper case" function. This is the standard way, and it is a good test of whether the syntax has clicked.
@concat(toUpper(substring(triggerBody()?['Name'], 0, 1)), substring(triggerBody()?['Name'], 1))
Read it inside out: take the first character, upper-case it, then glue on everything from character 1 onwards.
Numbers
@add(triggerBody()?['Fee'], 500) @mul(triggerBody()?['Fee'], triggerBody()?['Qty']) @div(triggerBody()?['Fee'], 3) @int(div(10, 3)) @mod(10, 3) @formatNumber(1234567.891, 'N2')
add(), sub(), mul() and div(). Nested arithmetic gets ugly fast: "fee plus 18 per cent" is add(fee, mul(fee, 0.18)). Build it up in Compose actions rather than writing one enormous expression - your future self will thank you.Reading a long expression
Work from the inside out. Take this:
triggerBody()?['Name']gives "anita sharma"split(..., ' ')gives["anita", "sharma"]first(...)gives "anita"toUpper(...)gives "ANITA"
@triggerBody()?['Name'] @split(triggerBody()?['Name'], ' ') @first(split(triggerBody()?['Name'], ' ')) @toUpper(first(split(triggerBody()?['Name'], ' ')))
Try these yourself
- Get the domain out of an email address using split and last.
- Write an expression that gives the first letter of the region in capitals.
- Add 18 per cent GST to a fee, and round it down to a whole number.
- Use coalesce to supply "Not given" whenever a phone field is empty.
- Explain what the ? does in ?[\x27Field\x27] and why you should always use it.
