Action
Actions in the Nativeblocks DSL. Attaching triggers to block events, chaining, the built-in script action, and imports.
Actions (also called triggers) run when a block fires an event: a tap, a text change, a form submission, or any custom event the block defines. You attach them to a block's event slots. Multiple actions in the same slot run in declaration order.
There are two kinds:
- Registered actions are custom logic generated from an installed integration. See Block & Action for how to build them.
- script is a built-in inline action for reading and writing variables and updating block properties without a separate integration.
Unlike blocks, actions have no slots and no visibility. Properties take a single value (no breakpoints), data binds a variable, and the only events are onNext, onSuccess, and onFailure, each chaining the next trigger.
Action factory
Registered actions are factory functions. Everything is a named argument: actionName, properties, data, and the chaining events.
analyticsAction(
actionName = "track",
route = "value", // property
payload = dataVar, // data
onNext = { // chain the next trigger
navigateAction(actionName = "nav")
},
)
| Parameter | Type | Description |
|---|---|---|
actionName (name in TypeScript) | string | Unique name for this action within the frame. Auto-generated if omitted. |
Properties
Action properties take a single value with no breakpoints.
analyticsAction(actionName = "track", route = "value")
Data
Data binds a frame variable. The action reads the variable's current value at runtime.
Data is a named argument whose name is the data key.
navigateAction(actionName = "nav", payload = routeVar)
Events
Actions support three chaining events. Only these three are valid:
| Event | When it runs |
|---|---|
onNext | After this action completes, regardless of outcome |
onSuccess | Only when this action succeeds |
onFailure | Only when this action fails |
Registered actions take chaining events as named-argument lambdas. The built-in script chains .onNext { }.
requestAction(
actionName = "request",
onSuccess = { showSuccessAction(actionName = "ok") },
onFailure = { showErrorAction(actionName = "err") },
)
script { _, updateVariable, _ ->
updateVariable(stepVar, "1")
}.onNext {
script { _, updateVariable, _ ->
updateVariable(stepVar, "2")
}
}
Attaching to blocks
Attach one or more actions to a block event. They run top to bottom.
nativeblocksButton(
blockKey = "btn",
onClick = {
navigateAction(actionName = "nav")
script { _, updateVariable, _ ->
updateVariable(loadingVar, "true")
}
},
)
Rules
- Actions do not return values. Communicate results by writing to frame variables.
- Actions inside the same event run in declaration order.
- Use
onNext/onSuccess/onFailureto chain actions that must run sequentially across async boundaries. - Avoid long-running or blocking work inside
script. - Every action name must be unique within a frame.
script
script is the built-in action for inline logic. The build closure receives three helper functions:
| Function | What it does |
|---|---|
getVariable(variable) | Produces the getVariable("key") read expression. The runtime returns the value as a string. |
updateVariable(variable, value) | Produces an updateVariable("key", …) write. value is a template string, embed another variable to splice in its live value. |
updateBlockProperties(key, property, values) | Updates a block's visual property at runtime without rebuilding the frame. |
The script body is JavaScript at runtime.
The build closure returns the JavaScript body string. Helper calls produce snippet strings; for computed writes, write JavaScript directly (v.key gives the variable's key).
// Single templated write: return the snippet directly
script { _, updateVariable, _ ->
updateVariable(myVar, "newValue")
}
// Reference another variable's live value with {{var:key}}
script { _, updateVariable, _ ->
updateVariable(greeting, "Hello {{var:userName}}")
}
// Read then compute: splice the read expression, write raw JavaScript
script { getVariable, _, _ ->
"""
let n = Number(${getVariable(myVar)});
updateVariable("${myVar.key}", String(n + 1));
""".trimIndent()
}
Optional name: script(name = "myScript") { ... }.
updateBlockProperties
The third argument is the property value per breakpoint. Pass only the breakpoints you want to change; omitted ones keep their current value. The key must match a block's blockKey in the same frame.
// Single breakpoint
updateBlockProperties("card", "backgroundColor", BlockPropValues(mobile = "#FF0000"))
// Multiple breakpoints
updateBlockProperties("card", "backgroundColor", BlockPropValues(
mobile = "#FF0000",
tablet = "#00FF00",
desktop = "#0000FF",
))
Common patterns
Boolean toggle
script { getVariable, _, _ ->
"""updateVariable("${flagVar.key}", String(${getVariable(flagVar)} !== "true"));"""
}
INDEX: current item in a repeating block
INDEX gives the current iteration index when a script runs inside a repeating block. It compiles to the {{index}} placeholder.
script { getVariable, _, _ ->
"let item = JSON.parse(${getVariable(listVar)})[$INDEX];"
}
Helper functions
When the same action sequence repeats, extract it into a helper declared outside the frame function.
Helpers must extend ActionsScope so action factory calls self-register:
fun ActionsScope.trackAndNavigate(routeVar: Variable) {
analyticsAction(actionName = "track", route = routeVar.value)
navigateAction(actionName = "nav", payload = routeVar)
}
fun frame(): NativeblocksFrame = androidFrame(name = "Home", route = "/home") {
rootBlock {
nativeblocksButton(blockKey = "btn", onClick = {
trackAndNavigate(routeVar)
})
}
}
Imports
import com.example.app.generated.integration.android.Script.script
import com.example.app.generated.integration.android.nativeblocks.navigate.navigateAction
script and INDEX live in the platform Script package; registered actions follow the same path pattern as blocks.