All articles

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.

· 7 min read

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) or Collect() (appends).

When to Use Each

ScenarioUseWhy
Store a value needed across screensSet (global variable)Only global variables survive screen navigation
Store a temporary UI state on one screenUpdateContext (context variable)Keeps it isolated, won’t collide with other screens
Show/hide a popup on the current screenUpdateContextYou don’t need this on other screens
Cache a table of data from DataverseClearCollect (collection)Collections hold tables, variables hold single values
Build a shopping cart or multi-select listCollect / RemoveCollections support adding and removing rows
Pass a value to the next screenSet or Navigate with contextSee “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:

  • var prefix for global variables: varCurrentUser, varIsAdmin
  • loc prefix for context variables: locShowPopup, locEditMode
  • col prefix 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.

Share this article LinkedIn X / Twitter

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.

· 7 min read