Skip to content
npm

Variables

Variables are named values defined once (in the Variables tab) and readable from every expression as {__variables.name}, or just {name} when it doesn't clash with an element name.

Variable types

The Type column decides where the value comes from:

TypeValue comes fromExample
routethe URL: route.id, route.params.id, route.queryParams.xxx, route.data.xxx, route.url/clients/42/editclientId = 42
externalcontext the host application provides via APIexternal.apiBaseUrl, external.user, external.features.list
constanta fixed value you typemaxUploadMb = 10
expressioncomputed from other dataisEditMode = notEmpty({__variables.route.id})
dataSourcethe result of a data sourcesettings loaded from the API
manualset at runtime by a Set value action or host code, never recalculated automaticallywizard state, selected row

Definition fields

Each row in the Variables tab has:

FieldWhat it does
NameIdentifier used in expressions: {__variables.name}.
TitleHuman label for the list.
TypeOne of the types above.
Value / SourceThe route path, external path, constant, expression, or data source name, depending on type.
FallbackUsed when the source resolves to nothing (e.g. no route param on /clients/new).
Target pathAlso write the value into the form data at this path.
To data JSONShip the value with the submitted data.
Reload data source when fields changeFor dataSource variables: re-run the source when watched fields change.
Listen fieldsComma-separated paths that trigger the reload. Reload runs only when one of these changes. Example: userId, data.user.type, filters.status.
RefreshManually re-resolve variables after structure or source changes.

When variables recalculate

An expression variable behaves like any other calculated value. It watches every field it references and recomputes the moment one of them changes, and anything reading the variable updates in the same pass. A chain like variable1 = {el1} + {el2} feeding an element with expression: {variable1} settles immediately, with no need to leave and re-enter the view.

Referencing a field the user has not filled in yet is fine. The variable simply resolves to nothing and falls back to Fallback if you set one, rather than showing a broken value.

Writing into a variable

Besides the Set value action, any expression can write into a variable:

text
{variable1} = sumArray({el1}, el5[].column3)
{variable1} += {row.column3}

Handy for running totals and for collecting rows out of a dynamic panel. A manual variable is the right type here, since nothing recalculates it behind your back. Details and the function form in Writing values back.

A total collected this way belongs to one run of the form, not to the view. Leaving Preview clears it along with the rest of the working data, so coming back into Preview starts from the fallback again instead of carrying on from the previous total.

Using variables

text
visibleIf:      {__variables.route.mode} != "view"
Default value:  {__variables.route.clientId}
disableIf:      {__external.userRole} != "admin"
Data source param:  id = {__variables.route.clientId}
Navigate to:    /clients/{__variables.route.clientId}/history

{__external.*} is a shortcut to everything the host application passed as external context, with no definition needed.

Example: edit vs. create mode

The same form serves /clients/new and /clients/42/edit:

  1. Variable clientId: source route, fallback empty.
  2. Variable isEdit: source expression, notEmpty({__variables.clientId}).
  3. Load panel data with source GET /api/clients/{id}, param id = {__variables.clientId} (skipped automatically when empty, so nothing loads in create mode).
  4. Page title element: dynamic text {{isEdit ? "Edit client" : "New client"}}.
  5. Save button condition: {__variables.isEdit}PUT action; otherwise POST action (two actions with opposite conditions).