5 min readRishi

15 Power Automate Expressions Every Maker Should Memorize

Most slow Power Automate builds are not slow because the maker is careless. They are slow because every small transformation becomes another action, another run-history click, and another place for nulls to break the flow. Memorizing a compact set of Workflow Definition Language expressions lets you design with intent instead of hunting through dynamic content.

Null handling deserves muscle memory

Start with safe defaults. coalesce is the expression I use most in production flows because connector responses are inconsistent. Dataverse might return a missing alternate phone number, SharePoint might return an empty person field, and an HTTP response might omit an optional property. coalesce gives the first non-null value, which is different from checking only for an empty string.

Use if when the branch is simple. If the decision spans multiple actions, use conditions. If the decision returns one value, keep it inside the expression. Combine that with equals, and, and or when the rule is readable in one line.

coalesce(triggerBody()?['email'], triggerBody()?['upn'], 'unknown@example.com')

if(empty(triggerBody()?['phone']), 'No phone supplied', triggerBody()?['phone'])

equals(toLower(triggerBody()?['status']), 'approved')

and(equals(triggerBody()?['status'], 'Approved'), not(empty(triggerBody()?['approver'])))

or(equals(triggerBody()?['priority'], 'High'), equals(triggerBody()?['vip'], true))

Dates are cleaner when you stop composing strings

Treat time as data, not text. utcNow gives you the current timestamp. formatDateTime turns dates into the shape the target system expects. addDays and addHours are the practical workhorses for service-level agreements, reminders, and expiry logic.

Use ticks for date math. When you need duration, convert two timestamps to ticks and subtract. One second is ten million ticks, so you can calculate hours or days without building fragile string comparisons.

utcNow()

formatDateTime(utcNow(), 'yyyy-MM-dd')

addDays(utcNow(), 7, 'yyyy-MM-ddTHH:mm:ssZ')

addHours(triggerBody()?['submittedOn'], 48)

div(sub(ticks(utcNow()), ticks(triggerBody()?['createdOn'])), 864000000000)

Arrays become predictable with a small toolkit

Check before you index. length tells you how many items you have. empty is the readable guard for arrays, strings, and objects. Use first and last only after you know the array is not empty, or wrap the access with a safe fallback.

Know your loop context. Inside Apply to each, item points at the current element. items points at a named loop. Use items when nested loops make item ambiguous. This one habit prevents a surprising number of wrong-record updates.

length(body('List_rows')?['value'])

empty(body('Filter_array'))

first(body('List_rows')?['value'])?['accountid']

last(outputs('Compose_OrderLines'))?['sku']

item()?['name']

items('Apply_to_each_contact')?['emailaddress1']

Action outputs are contracts you should read directly

Use outputs when you need the whole action result. It includes headers, status code, and body for many actions. Use body when you want the payload only. Both are more stable than repeatedly selecting dynamic content tokens after a rename.

Convert intentionally. json parses text into an object or array. string serializes a value for logging, comparison, or transport. Avoid bouncing values between string and object forms unless you have a reason.

outputs('HTTP')?['statusCode']

body('HTTP')?['value']

json(outputs('Compose_RawPayload'))?['customer']?['name']

string(body('Get_a_row_by_ID')?['revenue'])

Text shaping is usually one expression away

Use simple transformations close to the source. replace cleans known characters. split turns delimited text into an array. join turns an array into a readable string. createArray is useful when a later action demands an array even though you only have one or two known values.

replace(triggerBody()?['phone'], ' ', '')

split(triggerBody()?['tags'], ',')

join(body('Select_EmailAddresses'), ';')

createArray(triggerBody()?['primaryEmail'], triggerBody()?['secondaryEmail'])

variables('retryCount')

A quick reference keeps reviews focused

Use this table during design reviews. It is not a syntax encyclopedia. It is the shortlist that catches the most production bugs and removes the most unnecessary actions.

ExpressionUse it forProduction note
coalesceFallback valuesHandles null, not every blank string scenario
ifInline branchingKeep it short or use a Condition
equals, and, orBoolean rulesNormalize case before comparing user text
formatDateTimeDate display and API formatsAlways specify the format
addDays, addHoursDeadlines and windowsBe clear about UTC versus local expectations
utcNowCurrent timestampPrefer it over local time in automation
ticksDuration mathConvert results into days or hours explicitly
length, emptyGuardsCheck arrays before using first
first, lastBoundary recordsSafe only when the array has data
item, itemsLoop recordsUse named items in nested loops
outputs, bodyAction resultsoutputs is broader, body is cleaner
json, stringType conversionConvert once at the boundary
replace, split, joinText cleanupPrefer Select for object reshaping
createArraySmall arraysUseful for consistent downstream schemas
variablesShared stateAvoid variables inside concurrent loops

The best expressions remove actions, not readability

The goal is leverage. A flow with five expressive Compose actions is better than a flow with twenty vague data operations. But a single monster expression is not senior engineering. The senior move is to put stable shaping in expressions, keep business decisions visible, and name every action as if the next person will debug it at 2 AM.

Name the intermediate steps when the expression becomes a contract. I still use Compose actions for important boundaries: normalized email, calculated due date, selected customer payload, or parsed API response. That gives you a stable token to reuse and a run-history checkpoint that explains the data shape. Expressions should remove accidental complexity, not erase evidence.

Memorize these expressions until they feel boring. Boring expressions are how you make Power Automate runs shorter, safer, and easier to explain when the business asks why one record took a different path.

Keep reading

Newsletter

New posts, straight to your inbox

One email per post. No spam, no tracking pixels, unsubscribe anytime.

Comments

No comments yet. Be the first.