Unify Logo Footer.svg
Unify Applications
Logo
Events & Actions Overview

Events & Actions Overview

Logo

9 mins READ

How Events and Actions Work

You make an app interactive by attaching events to a component (or to the page itself) and giving each event one or more actions. An event is the trigger — a click, a value change, a page load. An action is what runs in response — navigate, run a data source, set a variable, open a modal.

You configure interactions in a component's Interactions section using Add Interaction. For page-wide triggers, go to Page Settings → Events. Actions on the same event run in order, top to bottom.

Note: Where to configure: Application builder → select a component → Properties panel → Interactions tab → Add Interaction.

Event Node Anatomy

Internally, each event-action pair is stored as a node in the component's events array. Understanding this shape helps when reading generated configurations or debugging unexpected behavior.

JSON — event node structure

{ "eventType": "onClick", "id": "Evt_6VRjl", "action": { "actionType": "showNotification", "payload": { "type": "success", "title": "Saved successfully" }, "id": "act_674C5" } }

Key facts about the node shape:

  • eventType — the exact camelCase event key (e.g. onClick, onChange, onSubmit). The click event is always onClick — lowercase "on", uppercase "C".

  • id — platform-minted identifier beginning with Evt_ or evt_.

  • action — a single action node. Multiple actions on the same event are sibling entries in the array sharing the same eventType, executed in array order.

Event Types

Each component exposes the events that make sense for it. The table below covers the most common ones.

Event KeyTriggerAvailable On
onClickUser clicks the componentMost interactive components
onChangeValue changes in an input or selectText Input, Select, Checkbox, Date Picker, etc.
onSubmitForm is submittedForm block
onMouseEnterCursor moves over the componentMost visible blocks
onOpen / onCloseComponent opens or closesModal, Drawer, Bottom Sheet
onFocus / onBlurComponent gains or loses keyboard focusInput fields
onRowSelectA table row is selectedTable block
onPageChangeTable pagination changesTable block
onCellClick / onCellValueChangeA table cell is clicked or its value changesTable block
onStepChangeActive step changesStepper block
onFilterChangeFilter criteria changeFilters component
onFileUploadedFile upload completesFile Upload block
onDataPointClickUser clicks a data point on a chartChart blocks
onPageLoadPage finishes mountingPage-level events
onPageFocusBrowser tab regains focusPage-level events
onKeyboardShortcutA configured keyboard shortcut firesPage-level Keyboard Shortcuts
onReceiveMQTTEventMQTT message received on a subscribed topicPage-level events
onTimerExpireTimer block countdown endsTimer block
onSuccess / onFailureData source completes or errorsData source events

Action Catalog

The action picker groups available actions by category. The full list is shown below.

Data Actions

ActionWhat it does
controlDataSourceRe-runs or refreshes a data source on demand
controlBlockMethodCalls a named method on a target block (submit form, scroll into view, etc.)
triggerFunctionExecutes a manual page or app function
executeScriptRuns arbitrary JavaScript inline
ActionWhat it does
navigateGo to an external URL or raw path
navigateToPageGo to another page in the same app by page ID
navigateBackGo back in browser history
setURLParametersUpdate the current page's query string without navigating
openShareDialogOpen the OS share sheet or copy a shareable link

UI Control Actions

ActionWhat it does
controlModalOpen or close a Modal block
controlDrawerOpen or close a Drawer block
controlBottomSheetOpen or close a Bottom Sheet block
controlNavigationDrawerOpen or close the app's navigation drawer
showNotificationDisplay a toast/snackbar notification
submitFormProgrammatically submit a Form block
controlWalkthroughStart, stop, or advance a guided walkthrough
controlMediaViewerOpen or close a media viewer overlay

State Actions

ActionWhat it does
setPageVariableRead and write a page or app variable
setInterfaceSessionStorageWrite a value to browser session storage
setLocalStorageWrite a value to browser local storage

User & Data Actions

ActionWhat it does
controlUserLogout, change language/theme, refresh user context
copyToClipboardWrite a value to the clipboard
exportDataExport records to CSV, XLS, or XLSX
exportBlockExport a block as an image or PDF
downloadFileDownload a file from a URL
importObjectsImport records from a file upload

Event Actions

ActionWhat it does
emitPageEventEmit a named event that other components can listen for
sendMQTTEventPublish a message to an MQTT topic

Action Node Structure

Every action — regardless of type — follows the same node shape:

JSON — full action node

{ "actionType": "showNotification", "payload": { "type": "success", "title": "Record saved", "description": "Changes were applied." }, "id": "act_674C5", "runCondition": { "type": "filter", "payload": { "operator": "AND", "filters": [ { "property": "{{ variables.isAdmin }}", "filter": { "operator": "EQUAL", "value": "true" } } ] } }, "onSuccessActions": [ { "actionType": "navigate", "payload": { "path": "/dashboard" }, "id": "act_abc1" } ], "onErrorActions": [ { "actionType": "showNotification", "payload": { "type": "error", "title": "Failed" }, "id": "act_abc2" } ] }

FieldTypeRequiredDescription
actionTypestringRequired (required)The exact machine ID of the action (e.g. showNotification, navigate).
payloadobjectRequired (required)Action-specific parameters. Fields differ per actionType.
idstringRequired (required)Platform-minted identifier (act_…). Always present in practice.
runConditionConditionObjectOptional (optional)If provided, the action only runs when this condition evaluates to true. Must be an object ({ "type": "boolean", "payload": true } or a filter group) — never a raw string.
onSuccessActionsAction[]Optional (optional)Actions to run after this action succeeds. One level deep only.
onErrorActionsAction[]Optional (optional)Actions to run if this action fails. One level deep only.
delayDurationnumber (ms)Optional (optional)Milliseconds to wait before running. Used with executionType: "delay".
executionTypestringOptional (optional)delay, debounce, or throttle. Controls rate-limiting behavior.

Sequential vs Callback Execution

UnifyApps gives you three ways to chain actions. Choose based on whether subsequent actions depend on the prior action's success:

1. Sequential Steps (same event)

When you add multiple actions to one event, they run as sibling entries in array order. Use this for "do A then B" where B does not depend on whether A succeeded.

Pattern — sequential actions on onClick

{ "events": [ { "eventType": "onClick", "id": "Evt_001", "action": { "actionType": "setPageVariable", "payload": { "variableId": "var_abc", "value": "active" }, "id": "act_001" } }, { "eventType": "onClick", "id": "Evt_002", "action": { "actionType": "showNotification", "payload": { "type": "success", "title": "Done" }, "id": "act_002" } } ] }

2. Success/Failure Callbacks

Use onSuccessActions and onErrorActions on an action node when the follow-up only makes sense after the parent succeeds or fails. For example: save a record → on success navigate away, on failure show an error.

Warning: One level only. Callback actions cannot carry their own onSuccessActions/onErrorActions. The builder enforces this limit. For a second stage, use a sibling event entry instead.

3. Data Source Events

When you want to react to an async data source completing, put the follow-up actions on the data source's own onSuccess / onFailure events — not inside the action that triggered the data source. This is the correct pattern for "call an API, then show a success toast."

Conditional Execution

Each action supports a runCondition — a condition object that gates whether the action runs. If the condition evaluates to false, the action is skipped without error.

The condition object takes one of two forms:

Form 1 — boolean literal

{ "type": "boolean", "payload": true }

Form 2 — filter group (role-based gate)

{ "type": "filter", "payload": { "operator": "AND", "filters": [ { "property": "{{ user.role }}", "filter": { "operator": "EQUAL", "value": "admin" } } ] } }

Execution Strategy: Delay, Debounce, Throttle

Each action can have an execution strategy that rate-limits when it fires:

StrategyBehaviorUse Case
delayWaits delayDuration ms, then runsShow a tooltip after a 500 ms hover
debounceResets the timer on each trigger; runs after the quiet periodSearch-as-you-type — only fire after typing stops
throttleRuns at most once per delayDuration windowScroll events or rapid button clicks

Managing Events and Actions

In the builder's Interactions panel you can:

  • Reorder actions by dragging within the same event.

  • Copy an action to reuse its configuration elsewhere.

  • Disable an event or action without deleting it — disabled items are skipped at runtime and shown dimmed with a tooltip. Use this to temporarily switch off behavior while testing.

  • Add a confirmation dialog to require user acknowledgment before a destructive action runs.

Tip: Tip: Put a navigate or navigateToPage action last in a sequential chain. The runner continues executing later nodes even after a same-tab navigation (it does not cancel the loop), so a navigate mid-chain can lead to unexpected behavior.

End-to-End Example: Save & Navigate

A button that saves a record, shows a success toast, then navigates to a list page — or shows an error on failure:

Complete event handler — save button

{ "eventType": "onClick", "id": "Evt_saveBtn", "action": { "actionType": "controlDataSource", "payload": { "dataSourceId": "ds_saveRecord", "method": "trigger" }, "id": "act_save", "onSuccessActions": [ { "actionType": "showNotification", "payload": { "type": "success", "title": "Record saved" }, "id": "act_toast" }, { "actionType": "navigateToPage", "payload": { "pageId": "e_listPage", "target": "_self", "history": "push" }, "id": "act_nav" } ], "onErrorActions": [ { "actionType": "showNotification", "payload": { "type": "error", "title": "Save failed", "description": "{{ ds_saveRecord.error }}" }, "id": "act_err" } ] } }

Frequently Asked Questions

Can multiple actions run when a single event fires?

Yes. You can attach a sequence of actions to any event — they run one after the other, in the order you configure them. Each action's onSuccessActions and onErrorActions let you branch the chain based on whether the preceding step succeeded or failed.

How do I prevent an action from running unless certain conditions are met?

Use the runCondition field on the action node. Set it to a filter-type condition object referencing the variables or data you want to check. The action is skipped (without stopping the chain) when the condition evaluates to false.

What is the difference between delay, debounce, and throttle?

Delay waits a fixed number of milliseconds before running the action once. Debounce collapses rapid successive firings — it resets the timer every time the event fires and only runs after the quiet period ends. Throttle runs at most once per interval regardless of how many times the event fires during that window.

Do actions in onSuccessActions run in parallel or in sequence?

In sequence, in the order listed. Each subsequent action waits for the previous one to complete (or fail). If you want actions to run truly in parallel, place them as siblings in the main action list rather than in a nested callback list.

What happens if an action without an onErrorActions block fails?

The error is swallowed silently and the chain stops at that point. To surface failures, add an onErrorActions block with a showNotification action or a variable write that records the error.