Set vs UpdateContext vs Collect — Power Apps Variables Explained
Power Apps has three ways to store data in memory: global variables, context variables, and collections. Here's when to use each one and the mistakes that trip up beginners.
Power Apps doesn’t have traditional variable declarations like let x = 5. Instead, you have three functions that each create a different kind of variable. Picking the wrong one leads to bugs that are annoying to track down.
The Three Variable Types
Global Variables (Set)
Set(varUserName, "John Smith")
Set(varIsAdmin, true)
Set(varItemCount, 42)
- Available on every screen in the app.
- Hold a single value (text, number, boolean, record, table).
- Created/updated with
Set().
Context Variables (UpdateContext)
UpdateContext({ locShowPopup: true })
UpdateContext({ locSelectedItem: Gallery1.Selected, locEditMode: true })
- Available only on the current screen.
- Hold a single value each.
- You can set multiple context variables in one call.
- Created/updated with
UpdateContext().
Collections (Collect / ClearCollect)
ClearCollect(colEmployees, Employees)
Collect(colCart, { Product: "Widget", Qty: 3 })
- Available on every screen (global).
- Hold a table of records (multiple rows and columns).
- Created with
ClearCollect()(replaces contents) orCollect()(appends).
When to Use Each
| Scenario | Use | Why |
|---|---|---|
| Store a value needed across screens | Set (global variable) | Only global variables survive screen navigation |
| Store a temporary UI state on one screen | UpdateContext (context variable) | Keeps it isolated, won’t collide with other screens |
| Show/hide a popup on the current screen | UpdateContext | You don’t need this on other screens |
| Cache a table of data from Dataverse | ClearCollect (collection) | Collections hold tables, variables hold single values |
| Build a shopping cart or multi-select list | Collect / Remove | Collections support adding and removing rows |
| Pass a value to the next screen | Set or Navigate with context | See “Passing Data Between Screens” below |
Practical Examples
Toggle a Popup
// Button.OnSelect
UpdateContext({ locShowDialog: true })
// Popup container.Visible
locShowDialog
// Close button inside popup
UpdateContext({ locShowDialog: false })
Track the Currently Selected Record Across Screens
// Gallery.OnSelect (Screen 1)
Set(varSelectedAccount, ThisItem);
Navigate(DetailScreen)
// Label on DetailScreen
varSelectedAccount.'Account Name'
Cache Data for Offline-Style Performance
// App.OnStart
ClearCollect(colProducts, Products);
ClearCollect(colCategories, Categories)
// Gallery.Items (uses cached data, no server calls)
Filter(colProducts, Category = drpCategory.Selected.Value)
Add Items to a Collection
// "Add to Cart" button
Collect(
colCart,
{
ProductName: ThisItem.Name,
Price: ThisItem.Price,
Quantity: Value(txtQty.Text)
}
)
Remove from a Collection
// "Remove" button in cart gallery
Remove(colCart, ThisItem)
Clear a Collection
Clear(colCart)
Passing Data Between Screens
Context variables don’t travel between screens — that’s by design. You have two options:
Option 1: Use a global variable
// Screen 1
Set(varSelectedId, ThisItem.ID);
Navigate(Screen2)
// Screen 2
LookUp(Accounts, ID = varSelectedId)
Option 2: Pass context with Navigate
// Screen 1
Navigate(Screen2, ScreenTransition.None, { locAccountId: ThisItem.ID })
// Screen 2 — locAccountId is now a context variable on Screen2
LookUp(Accounts, ID = locAccountId)
Option 2 is cleaner because it doesn’t leave global variables floating around, but it only works for the initial navigation. If the user navigates to Screen2 from somewhere else, locAccountId will be blank.
Naming Conventions
There’s no enforcement, but a consistent naming convention saves you time in larger apps:
varprefix for global variables:varCurrentUser,varIsAdminlocprefix for context variables:locShowPopup,locEditModecolprefix for collections:colProducts,colCartItems
This makes it obvious in any formula which type of variable you’re looking at and where it’s available.
Performance Notes
Collections are stored in memory. If you ClearCollect a table with 50,000 rows, you’re loading all of them into the app’s memory. For large datasets, filter before collecting:
// Bad: loads everything
ClearCollect(colContacts, Contacts)
// Better: loads only what you need
ClearCollect(colContacts, Filter(Contacts, 'Company Name' = varSelectedAccount))
Global variables persist for the app session. Setting 50 global variables won’t cause performance issues, but storing large records or tables in them can increase memory usage.
Common Mistakes and How to Fix Them
UpdateContext Variable Is Blank on Another Screen
Context variables only exist on the screen where they were created. If you set UpdateContext({ locName: "John" }) on Screen1 and then navigate to Screen2, locName doesn’t exist on Screen2.
Fix: Use Set() for cross-screen values, or pass the value through Navigate().
ClearCollect vs Collect Confusion
Collect appends rows. If you call Collect(colItems, Products) twice, you get duplicates. ClearCollect replaces the entire collection contents.
Rule of thumb: use ClearCollect when loading/refreshing data, use Collect when adding individual items.
Variable Shows Old Value After Navigating Back
If you navigate away from a screen and come back, context variables may still hold their previous values (they don’t reset automatically). If you need fresh state on each visit, reset them in the screen’s OnVisible:
// Screen.OnVisible
UpdateContext({ locEditMode: false, locShowPopup: false })
“Set is not supported in this context”
Set() and UpdateContext() are behavioral functions — they can only be used in action properties like OnSelect, OnVisible, OnChange, etc. You can’t use them in display properties like Text or Items.
If you need a calculated value for display, use the expression directly in the property or use App.Formulas for named formulas.
Collection Columns Don’t Match the Data Source
If you build a collection manually with Collect(col, { Name: "x", Count: 5 }) and later try to Patch it into a Dataverse table, the column names must match exactly. Dataverse display names are case-sensitive and may include spaces. Check the exact column names in the table designer.
Related articles
Subgrids Done Right
Subgrids show related records directly on a form. Here's how to add them, choose the right relationship, filter the records, enable inline editing, and set up a New button that pre-fills the parent lookup.
Blanks and Nulls in Power Apps: Why Your Formulas Keep Breaking
Blank values in Power Apps cause unexpected errors, wrong comparisons, and broken lookups. Here's how to check for them, handle them safely, and stop your formulas from silently failing.
Cascading Dropdowns in Canvas Apps (Yes, It's Harder Than It Should Be)
A parent dropdown for Country, a child dropdown for City that only shows cities in the selected country. Here's the pattern, the delegation-safe version, and the reset behavior that catches everyone.