Tutorials/Power Apps/Hidden Gems: 7 Overlooked Power Apps Functions That Solve Real Problems
Power Appsintermediate

Hidden Gems: 7 Overlooked Power Apps Functions That Solve Real Problems

Move beyond the basics with seven Power Apps functions that often get ignored—learn how they can simplify your formulas, improve performance, and unlock new possibilities.

NA
Narmer Abader
@narmer · Published June 3, 2026

When you start building canvas apps, you quickly learn the heavy hitters: If, Filter, Patch, Collect. But Power Apps ships with over a hundred functions, and some of the most useful ones rarely make it into tutorials. Over the course of building a real-world project management tool, I discovered seven functions that solved problems I used to work around with awkward workarounds. This article walks through each one with a concrete scenario—a simple Task Tracker app connected to a SharePoint list—so you can see how they fit into a real app.

The Scenario: A Lean Task Tracker

We're building a small app to track team tasks. The underlying SharePoint list has these columns:

  • Title (text)
  • Owner (Person or Group)
  • Deadline (Date and Time)
  • Status (Choice: Not Started, In Progress, Done)
  • Priority (Choice: Low, Medium, High)
  • Category (Choice: Development, Design, Marketing, Other)

The app needs to let users add tasks, animate a prompt when a task is overdue, combine two collections for a clean dropdown, generate blank rows for quick data entry, debug variable values, send task summaries to Power Automate, and assign unique keys to records that lack them. Each of these needs one of our hidden gems.


1. Coalesce – The Empty‑Value Safety Net

Coalesce takes a list of values and returns the first one that isn't blank. It’s shorter than If(IsBlank(...), ...) and reads more clearly.

In the Task Tracker: When a user adds a task but leaves the Priority field empty, we want to default to Medium. The formula in the OnSelect of the Submit button:

powerfxApplying a default priority
Patch(
  ProjectTasks,
  Defaults(ProjectTasks),
  {
      Title: TaskTitleInput.Text,
      Owner: User().Email,
      Deadline: DeadlineDatePicker.SelectedDate,
      Status: "Not Started",
      Priority: Coalesce(PriorityDropdown.Selected.Value, "Medium"),
      Category: CategoryDropdown.Selected.Value
  }
)

I also use Coalesce to write a single Patch that works for both insert and update:

powerfxUpsert pattern with Coalesce
Patch(
  ProjectTasks,
  Coalesce(
      LookUp(ProjectTasks, ID = varRecordID),
      Defaults(ProjectTasks)
  ),
  {
      Title: TaskTitleInput.Text,
      Owner: User().Email,
      Status: StatusDropdown.Selected.Value,
      Priority: Coalesce(PriorityDropdown.Selected.Value, "Medium")
  }
)

Without Coalesce you'd need two separate Patch calls inside an If, which clutters the app and makes maintenance harder.

Delegation note

Coalesce itself is not delegation‑aware, but when used inside LookUp it works fine because LookUp already delegates. For large data sources, avoid using it directly in a Filter that expects full delegation.


2. Sin – Natural‑Feeling Animation

Sin (sine) is a trigonometric function, but in canvas apps it shines for creating smooth, bouncy animations without a custom component.

In the Task Tracker: We want a small arrow icon to bounce up and down next to any task whose deadline has passed, urging the user to act. The icon’s Y property uses:

powerfxBounce animation with SIN
160 - Sin(Timer1.Value / Timer1.Duration * 2 * Pi()) * 40

Set up a timer:

PropertyValue
Autostarttrue
Duration1000
Repeattrue

The 160 is the resting Y‑position, and * 40 controls the bounce amplitude. The result is a fluid vertical oscillation that looks far more organic than jumping between two static Y values.

Performance tip

Use Sin animations sparingly—animating too many elements at once can hurt frame rate on low‑end devices. Limit to one or two prompter icons per screen.


3. Ungroup – Clean Dropdowns with a Blank Option

Ungroup reverses a GroupBy operation, but it can also be used creatively to build a dropdown that includes a blank option at the top.

In the Task Tracker: We need a dropdown that lists all Category values plus an empty item at the top so the user can clear the selection. The formula for the dropdown’s Items property:

powerfxDropdown with blank first option
Ungroup(
  Table(
      {CatItems: Table({Result: Blank()})},
      {CatItems: RenameColumns(
          Distinct(ProjectTasks, Category),
          "Result",
          "Value"
      )}
  ),
  "CatItems"
)

This wraps a blank record and the distinct categories into a single column table via Ungroup. The dropdown now shows a blank first line, and when the user selects it, the filter returns all records.

Alternative approaches (like using Collect to prepend a blank) require mutating a global collection. Ungroup does it declaratively.

Delegation awareness

Distinct delegates to supported data sources (like SharePoint) for the count of distinct values, but the table construction with Ungroup happens client‑side. Performance is fine for lists up to a few hundred distinct values.


4. Sequence – Generate Numbers, Dates, and Blank Rows

Sequence creates a single‑column table of numbers from 1 to N. Combine it with ForAll to build arrays of dates, characters, or even empty rows.

In the Task Tracker: The user can choose how many blank rows they want in a gallery for quick data entry. The gallery’s Items property:

powerfxGallery with user‑defined number of blank rows
ForAll(
  Sequence(Value(RowCountInput.Text)),
  {Title: Blank(), Owner: Blank(), Deadline: Blank(), Status: "Not Started"}
)

When the user types 5 in RowCountInput, the gallery shows 5 blank rows. After editing, they batch‑submit all rows with a single Collect wrapped in a ForAll.

Another neat use: generate the next 7 days for a date picker:

powerfxNext 7 days dropdown
ForAll(Sequence(7), {DateValue: Today() + Value})
Performance tip

Be careful with large values in Sequence. Generating thousands of rows client‑side can slow down the app. For the blank‑row scenario, cap the input to a reasonable number (e.g., 20).


5. Trace – Debugging Without Set Variables

Trace sends a message to the Monitor tool (and optionally to Azure Application Insights). It’s perfect for logging variable values during development without cluttering your app with labels.

In the Task Tracker: We suspect the status update logic has a bug. The OnSelect of the Complete button:

powerfxDebug with Trace
Set(localStatus, StatusDropdown.Selected.Value);
Trace("Status before Patch: " & localStatus, Trace.Severity.Info);
Patch(
  ProjectTasks,
  Gallery1.Selected,
  {Status: "Done"}
);
Trace("Status after Patch: " & localStatus, Trace.Severity.Info)

Open the Monitor tool (from the Advanced tools menu) and watch the output as you press the button. You can see the exact flow of your app in real time.

Trace also supports severity levels and custom records, which is invaluable when you start monitoring production apps with Application Insights. But even without that, the Monitor integration alone makes it a top debugging tool.

Common mistake

Forgetting to remove Trace calls from the final published app can clutter logs and (if Application Insights is connected) incur data costs. Use a global flag like varDebugMode to conditionally enable tracing.


6. JSON – Bridge to Power Automate

JSON converts a Power Apps table (collection, data source subset) into a JSON text string. This is the easiest way to pass structured data to a Power Automate flow.

In the Task Tracker: When the user clicks “Send Summary”, we gather all overdue tasks into a collection, convert it to JSON, and call a flow that sends an email.

powerfxConvert collection to JSON and call flow
ClearCollect(colOverdueTasks, Filter(ProjectTasks, Status <> "Done", Deadline < Today()));
OverdueTasksFlow.Run(
  JSON(colOverdueTasks, JSONFormat.IncludeBinaryData)
)

Inside the flow, add a Parse JSON action using this schema (auto‑generated from a sample). Then loop over the parsed array to send individual emails.

Size limits

Power Apps flow triggers have a payload limit of about 10 MB. If your collection is large, either send in batches or pass only the necessary columns with ShowColumns before converting.


7. GUID – Unique IDs When You Need Them

GUID generates a globally unique identifier—a 32‑character hex string with dashes. It’s deterministic enough to use as a primary key when your data source doesn’t provide one.

In the Task Tracker: We occasionally collect data into a local collection and later batch‑Patch it to SharePoint. Before saving, we assign a temporary ID so we can update records later even if duplicates exist.

powerfxAdd a GUID local key
ClearCollect(
  colTempTasks,
  AddColumns(
      colTaskInputs,
      "TempID",
      GUID()
  )
)

Now each row has a unique TempID. When we later Patch each record back to SharePoint, we can use TempID to identify the exact row, avoiding ambiguity with records that have identical names.

GUID is also useful for generating random passwords or tokens, though for security‑sensitive scenarios you should rely on a server‑side generator.

Delegation and storage

GUID is a client‑side function. If you need the ID to be generated inside a data source (to avoid race conditions), use your datasource’s auto‑increment or NewGuid() in SQL. For local collections, GUID is perfectly safe.


Common Mistakes and Troubleshooting

  • Coalesce expects its arguments to be evaluated in order. If you pass an expensive function (like a Filter with a large source) as the first argument, it runs even if a later argument is used. Keep lightweight values early.
  • Ungroup fails if the column name passed as the second argument doesn’t exist exactly (case‑sensitive in most data sources). Double‑check spelling.
  • Sequence + ForAll creates a new scope for ThisRecord.Value. If you need the iteration index, use ForAll(Sequence(N), { Index: Value, ... }).
  • Trace output in Monitor is not persisted beyond the session unless you set up Application Insights. Don’t rely on it for long‑term auditing.
  • JSON without JSONFormat.IncludeBinaryData may strip important media or attachment data. Use IncludeBinaryData only when needed because it increases size.
  • GUID collisions are astronomically unlikely, but if you merge collections from multiple devices, consider adding a device prefix.

Final Recommendation

These seven functions—Coalesce, Sin, Ungroup, Sequence, Trace, JSON, and GUID—each address a common pain point that many app makers solve with more verbose or brittle formulas. Taking the time to weave them into your toolkit will make your apps cleaner, more performant, and more maintainable.

Start by picking one that resonates with a problem you face today. For example, if you’re tired of writing multi‑branch If statements to handle blank values, refactor one screen to use Coalesce tomorrow. Over the next few weeks, you’ll wonder how you ever managed without them.


References