App Studio
Setting Variables
variables.set('name', value) is the primary way Custom JS communicates with the rest of the app. Setting a variable triggers a reactive update — every widget that binds to that variable re-evaluates its token expressions and re-renders if the value changed.
Basic Usage
// Set a computed total from DataGrid data
function onDataChange(widget, variables, actions, context) {
const rows = widget.data?.rows ?? [];
const total = rows.reduce((sum, r) => sum + (r.dealValue ?? 0), 0);
variables.set('totalDealValue', total);
// → All widgets using {{ variables.totalDealValue }} re-render with the new value
}
Variables Must Be Declared First
Before setting a variable from Custom JS, it must be declared in the App Variables panel (App Settings → Variables). Setting an undeclared variable is a no-op — it will not create a new variable at runtime:
// App Variables declaration (in App Studio App Settings → Variables):
{
"name": "totalDealValue",
"type": "number",
"defaultValue": 0
}
// Then in Custom JS:
variables.set('totalDealValue', 42500); // Works — variable is declared
variables.set('undeclaredVar', 99); // Ignored — not declared
Supported Value Types
| Type | Example | Notes |
|---|---|---|
| number | variables.set('count', 42) | Integers and floats |
| string | variables.set('label', 'Active') | Any string value |
| boolean | variables.set('isLoaded', true) | Used for visibility toggle patterns |
| object | variables.set('summary', { count: 5, total: 1200 }) | Object variables; use dot notation in tokens: {{ variables.summary.total }} |
| array | variables.set('selectedIds', ['id-1', 'id-2']) | Useful for multi-select state |
| null | variables.set('activeRecord', null) | Clears the variable to its null state |
Reading Before Writing
// Read the current filter state, toggle it, write it back
function onUserAction(widget, variables, actions, context) {
const currentFilter = variables.get('showOnlyActive'); // boolean
variables.set('showOnlyActive', !currentFilter); // toggle
}
Batch Setting Multiple Variables
Set multiple variables in sequence within a single script execution. All changes are applied as a batch — the reactive system processes them together, avoiding multiple intermediate re-renders:
function onDataChange(widget, variables, actions, context) {
const rows = widget.data?.rows ?? [];
const activeRows = rows.filter(r => r.status === 'active');
const closedRows = rows.filter(r => r.status === 'closed');
variables.set('activeCount', activeRows.length);
variables.set('closedCount', closedRows.length);
variables.set('totalValue', rows.reduce((s, r) => s + (r.value ?? 0), 0));
variables.set('avgValue', rows.length > 0 ? total / rows.length : 0);
// All four updates processed together — single re-render pass
}
Avoid infinite loops
If Widget A sets a variable on
onDataChange, and that variable is a data source param for Widget A itself, setting it will trigger Widget A to reload, which fires onDataChange again. Guard against this with a previous-value check or by using a separate derived variable that Widget A does not bind its own data source to.