Hello! Welcome back to our sixth module on developing with Power Automate.
In the previous lesson, you learned how to implement automated flows that trigger based on events in Dataverse and SharePoint. You mastered configuring triggers for specific conditions, which is crucial for building efficient automations. That was the "when" of automation; today, we focus on the "what" — what to do with the data once your flow is running.
This lesson addresses the learning outcome: Use expressions and built-in functions for data transformation within a flow. Expressions are the backbone of any dynamic flow, allowing you to manipulate strings, calculate dates, evaluate logic, and reshape data on the fly. Given your background in C# and .NET, you can think of expressions as the equivalent of inline methods or lambda expressions that operate on data as it moves through your workflow.
We'll start by understanding why expressions are critical for performance, then dive into the various categories of functions, and finally, look at practical patterns for transforming data.
1. Why Expressions Matter: Performance and Efficiency
Before we get into the syntax, it's important to understand why leaning on expressions is a best practice for professional Power Platform development. In many cases, you can achieve a result using either a series of "data operation" actions or a single, well-crafted expression. For a developer concerned with performance and scalability, the choice is clear.
Power Automate Performance Optimization with Expressions
This article, 'Power Automate Performance Optimization with Expressions,' makes a strong case for using expressions over multiple actions. It aligns with the professional developer's mindset of building clean, efficient, and scalable solutions.
Please read the sections titled 'Understanding Actions vs Expressions in Power Automate,' 'Why Expressions Beat Actions for Flow Optimization,' and review the 'Actions vs Expressions: Performance Comparison' table. Focus on how expressions lead to faster execution and reduced API calls.
As the article highlights, every action in a flow has an overhead and counts as an API call against your license limits. By using expressions, you perform the data manipulation within a single action, resulting in:
- Faster Flow Execution: Fewer steps mean less processing time.
- Reduced API Calls: Crucial for high-volume flows to stay within service limits.
- Cleaner, More Maintainable Flows: A single
Composeaction with a clear expression can be easier to read than three or four separate actions.
The Compose action is the most common tool for building and testing expressions. Think of it as a read-only variable where you can evaluate a formula and use its output in subsequent steps.
2. The Core Function Categories and Syntax
Power Automate expressions, which are based on the Power Fx language, are organized into several logical categories. The best way to get a feel for them is to see them in action.
The following video from Reza Dorrani is an excellent, comprehensive tutorial that covers the most important functions you'll use daily. We'll break it down by category.
Power Automate flow Expressions Tutorial
This 'Power Automate flow Expressions Tutorial' provides a practical, step-by-step walkthrough of the most common functions. It's a foundational video for mastering data transformation.
We will be referencing different parts of this video throughout the lesson. For now, watch from the beginning to 07:43 to understand the basic anatomy of an expression, the editor, and a quick overview of string functions.
As you saw in the video, expressions are written inside the expression editor, and dynamic content from previous steps can be mixed in. Let's explore the key function categories.
A. String Functions
These are used for text manipulation. You'll use these constantly for formatting email subjects, creating file names, or parsing text.
concat(text1, text2, ...): Joins strings together.split(text, separator): Splits a string into an array of substrings.replace(text, oldText, newText): Replaces occurrences of a substring.substring(text, startIndex, length): Extracts a portion of a string.toLower(text)/toUpper(text): Converts case.trim(text): Removes leading/trailing whitespace.indexOf(text, searchText): Finds the position of a substring.
B. Date and Time Functions
A critical point to remember is that Power Automate processes all dates and times in UTC format. You must always be conscious of converting to and from the user's local time zone for display purposes.
utcNow(): Gets the current date and time in UTC.formatDateTime(timestamp, format): Converts a date to a specified string format (e.g., 'yyyy-MM-dd').addDays(timestamp, days): Adds (or subtracts, with a negative number) days to a date.convertFromUtc(timestamp, destinationTimeZone): Converts a UTC time to a specific time zone.
C. Logical and Math Functions
These functions are the building blocks for conditions.
equals(value1, value2): Checks for equality.and(expr1, expr2)/or(expr1, expr2): Evaluates logical conditions.greater(val1, val2)/less(val1, val2): Comparison functions.if(expression, valueIfTrue, valueIfFalse): Ternary conditional logic.min(...)/max(...): Finds the minimum or maximum value in a set of numbers.
D. Collection (Array) Functions
These functions operate on arrays of data, which you often get from actions like 'Get items' or 'List rows'.
length(collection): Returns the number of items in an array.first(collection)/last(collection): Gets the first or last item.skip(collection, count): Returns an array that skips the first N items.union(coll1, coll2): Combines two arrays, removing duplicates.
For a complete reference, you can use the following guide. It's a great resource to bookmark for looking up specific functions and their syntax.
Power Automate Functions Reference Guide
This 'Power Automate Functions Reference Guide' is a handy cheat sheet that lists functions by category. It's a useful companion to the video material.
You don't need to read this from start to finish. Just skim the 'Text Functions,' 'Collection Functions,' 'Logical Functions,' 'Conversion Functions,' 'Math Functions,' and 'Date and Time Functions' sections to see the breadth of what's available. Keep this link handy for future reference.
3. Advanced Data Transformation Patterns
Now, let's move beyond individual functions and look at how to combine them to solve common development problems.
Pattern 1: Parsing Complex JSON and Avoiding Loops
When an action returns an array, Power Automate will often try to automatically add an 'Apply to each' loop if you use a property from that array. This is often unnecessary, especially if you know you only need the first item or are dealing with a single-item array.
Furthermore, you can often parse data directly from a JSON object without using the 'Parse JSON' action. This is a more performant and robust method for developers who are comfortable with JSON structures.
Power Automate flow Expressions Tutorial
Let's return to Reza Dorrani's video. This section demonstrates two incredibly powerful, developer-centric techniques: traversing JSON structures directly with expressions and avoiding unnecessary 'Apply to each' loops.
Watch from 16:34 to 26:19. Pay close attention to: How to access properties in a JSON object and items in an array using bracket notation: outputs('ActionName')?['body']?['propertyName'][0]. The use of the null-conditional operator (?) to prevent errors when a property might not exist. This is analogous to C#'s null-conditional operator. The practical example of avoiding a loop when getting an approver's comments from the responses array.
This technique gives you precise control over data access and is fundamental to building clean, efficient flows. Here is an example of what an expression looks like in the underlying code of a flow action, which should look familiar.

Pattern 2: Reshaping and Filtering Arrays
A very common task is to take an array of data from a source like Dataverse, filter it down to a relevant subset, and then transform its structure (e.g., rename, remove, or combine columns) before passing it to another system or creating a table for an email. The Filter array and Select data operations are perfect for this.
7 Power Automate Data Operations: Complete Power Platform Guide with Real Email & CSV Use Cases
This video from DamoBird365 focuses on the 'data operations' actions and provides a clear, real-world use case for transforming an array of data into a filtered and reshaped HTML table.
Watch the sections covering 'Parse JSON' (02:33 - 05:13), 'Filter array' (05:13 - 07:33), and the 'Select' action (08:36 - 11:22). Notice how the output of one action becomes the input for the next, creating a data transformation pipeline.
- Filter array: Takes an array and an expression that evaluates to true or false for each item. It outputs a new array containing only the items that satisfy the condition.
- Select: Takes an array and allows you to define a new structure. You map new keys (column names) to values from the source array, effectively reshaping the data. This is very similar to the
Selectmethod in LINQ. For example, you can transform[{ "firstName": "John", "lastName": "Doe" }]into[{ "FullName": "John Doe" }].
Test your understanding!
You have a Compose action named Compose_User_Data that contains the following JSON array:
[
{
"fullName": "Jane Doe",
"email": "jane.doe@example.com",
"lastLogin": "2023-10-15T10:00:00Z"
},
{
"fullName": "John Smith",
"email": "john.smith@example.com",
"lastLogin": "2024-05-20T12:30:00Z"
}
]
You need to create an expression for a Select action that transforms this array into a new array with a different structure. The output should look like this:
[
{
"Recipient": "Jane Doe <jane.doe@example.com>",
"Status": "Inactive"
},
{
"Recipient": "John Smith <john.smith@example.com>",
"Status": "Active"
}
]
The "Status" should be "Active" if lastLogin is within the last 90 days, and "Inactive" otherwise. How would you configure the Map section of the Select action?
Show answer
In the Select action, you would configure the mapping as follows:
-
From:
outputs('Compose_User_Data') -
Map (Key-Value pairs):
-
Key:
Recipient -
Value (Expression):
concat(item()?['fullName'], ' <', item()?['email'], '>') -
Key:
Status -
Value (Expression):
if(greater(item()?['lastLogin'], addDays(utcNow(), -90)), 'Active', 'Inactive')
-
This solution combines string (concat), date (addDays, utcNow), and logical (if, greater) functions, along with the item() function to refer to the current item being processed by the Select action.
Conclusion
Mastering expressions is a key differentiator for a Power Platform developer. It allows you to move beyond the basic drag-and-drop functionality and build sophisticated, performant, and robust automations.
Key Takeaways:
- Expressions are inline functions that are more performant than using multiple discrete actions, as they reduce execution time and API calls.
- The
Composeaction is an invaluable tool for building, testing, and debugging your expressions. - Functions are categorized into String, Date/Time, Logical, Collection, and more. Always be mindful of UTC for date operations.
- You can directly parse JSON and access specific array elements using bracket notation (
[]) and the null-safe operator (?) to create cleaner and more efficient flows. - Use the Filter array and Select actions as a powerful pipeline to filter and reshape data to your exact needs, much like you would use
WhereandSelectin LINQ.
Up Next:
Now that you can trigger flows and transform the data within them, the next logical step is to control the flow's execution path based on that data. In the next lesson, we will implement control flow logic using conditions, switch cases, and apply-to-each loops, putting your new expression skills to immediate and practical use.