Skip to main content

Standard and Standalone Actions

Standalone Actions

Sometimes reusable state-changing logic does not belong to a particular model class but still needs action protection and middleware support. For example, an array-swap helper should be visible to undoMiddleware. Define that logic as a standalone action:

const arraySwap = standaloneAction(
"myApp/arraySwap",
<T>(array: T[], index1: number, index2: number): void => {
if (index2 < index1) {
;[index1, index2] = [index2, index1]
}
// since a same node cannot be in two places at once we will remove
// both then reinsert them
const [v1] = array.splice(index1, 1)
const [v2] = array.splice(index2 - 1, 1)
array.splice(index1, 0, v2)
array.splice(index2, 0, v1)
}
)

Note the following prerequisites apply to standalone actions:

  • The name provided must be unique across your whole application.
  • The first argument (the target) must always be an existing tree node.

standaloneFlow

If the same idea needs asynchronous steps, use standaloneFlow. It follows the same rules as standaloneAction, but behaves like a flow and returns a promise:

const renameAfterSave = standaloneFlow(
"myApp/renameAfterSave",
function* (todo: Todo, newText: string) {
// like model flows, use `yield* _await(X)` where you would use `await X`
yield* _await(api.saveTodo(todo.id, { text: newText }))
todo.setText(newText)
}
)

This is useful when you want middleware support for reusable async logic without attaching that logic to a specific model class.

Standard Actions

Use the predefined objectActions and arrayActions to update objects and arrays without declaring custom actions. These helpers also work on class-model properties.

objectActions work over any kind of object (including models themselves) and offer:

  • set(obj, key, value) to set a key.
  • delete(obj, key) to delete a key.
  • assign(obj, partialObj) to assign values (similar to Object.assign).
  • call(obj, methodName, ...args) to call a method.

arrayActions work over arrays and offer:

  • set(array, index, value) to set an index.
  • delete(array, index) to delete an index.
  • setLength(array, length) to set a new length.
  • swap(array, index1, index2) to swap two array elements.

It also exposes the usual mutating array methods, including pop, push, shift, unshift, splice, reverse, and sort.