Advanced Power Fx & Canvas Components
Go beyond basic formulas. Learn complex Power Fx patterns, build reusable component libraries, and integrate Power Automate flows directly from canvas apps.
Power Fx for developers
Think of Power Fx as Excel formulas on steroids.
If you have ever written a VLOOKUP or an IF formula in a spreadsheet, you already know the basics of Power Fx. But Power Fx goes much further β it handles tables, records, collections, API calls, and even imperative (step-by-step) logic.
As a PL-400 developer, you need to know the advanced patterns: named formulas that calculate once and share across the app, imperative formulas that run steps in sequence, and component libraries that let you build a control once and reuse it in every app.
Advanced Power Fx patterns
Named formulas
Named formulas define values once and reuse them across the app. They recalculate automatically when dependencies change.
// In App.Formulas (app-level named formulas)
ActiveEmployees = Filter(Employees, Status = "Active");
TotalSalary = Sum(ActiveEmployees, Salary);
AverageAge = Average(ActiveEmployees, Age);
Why named formulas matter:
- Calculate once, use everywhere (no redundant Filter calls on every screen)
- Automatically recalculate when source data changes
- Reduce formula complexity on individual controls
Imperative vs declarative patterns
| Pattern | Declarative | Imperative |
|---|---|---|
| Style | βWhat the result should be" | "What steps to takeβ |
| Keywords | Filter, Sort, Sum, Average | Set, Collect, Patch, Navigate |
| Where | Properties (Items, Text, Visible) | Behaviors (OnSelect, OnChange, OnStart) |
| Example | Filter(Orders, Status = "Open") | Collect(Cart, ThisItem); Navigate(Checkout) |
Power Automate integration from canvas apps
Canvas apps can call cloud flows to perform actions the app cannot do directly β like sending emails, calling external APIs, or running long computations.
How it works:
- Create a cloud flow with βPower Apps (V2)β trigger
- Define input parameters the app will send
- Define output parameters the flow will return
- In the canvas app, call the flow:
MyFlow.Run(param1, param2) - Handle the response:
Set(varResult, MyFlow.Run(param1, param2))
Best practices:
- Use flows for operations that should not run client-side (email, external API, data processing)
- Keep flow calls asynchronous when possible (do not block the user)
- Handle errors: wrap in
IfError()to catch flow failures gracefully - Pass only the minimum data needed (not entire records)
Scenario: Kai builds a submission flow integration
Kai builds a canvas app for logistics staff to submit shipment requests. When a user taps βSubmitβ:
- The app calls
SubmitShipment.Run(ShipmentID, DestinationCode, Priority) - The flow validates the destination against a reference table, calculates estimated cost, and creates a record in the Shipment table
- The flow returns
{Success: true, EstimatedCost: 450, TrackingNumber: "TRK-29381"} - The app displays the tracking number and cost
Why a flow? The validation requires calling an external API (shipping provider) and creating a Dataverse record with calculated fields β operations that are cleaner and more maintainable in a flow than in Power Fx formulas.
Building component libraries
Component libraries let you build reusable controls that can be shared across multiple canvas apps.
Component anatomy
Every canvas component has:
- Custom input properties β data the host app passes into the component
- Custom output properties β data the component passes back to the host app
- Custom function properties β callbacks the host app can call (e.g.,
Reset()) - Custom event properties β events the component can raise (e.g.,
OnItemSelected)
Design principles
- Single responsibility β each component does one thing well
- Configurable via properties β do not hardcode colours, labels, or data sources
- Stateless preferred β accept data through input properties, emit results through output properties
- Test independently β components should work in isolation before using them in an app
Kai builds a canvas app that displays a filtered list of shipments. The same filter (Status = 'Active' AND Region = varUserRegion) is used on three different screens, where varUserRegion is set from the user's profile at app start. What is the best approach to avoid redundant evaluation?
A canvas app needs to send an email with an attachment when the user taps a button. The attachment is a PDF generated from form data. Where should this logic be implemented?
π¬ Video coming soon
Next up: Troubleshoot & Optimise Apps β using Monitor and browser tools to debug issues, and optimising performance with delegation and pre-loading.