.claude/skills/asyncredux-dispatching-actions/SKILL.md
--- name: asyncredux-dispatching-actions description: Dispatch actions using all available methods: `dispatch()`, `dispatchAndWait()`, `dispatchAll()`, `dispatchAndWaitAll()`, and `dispatchSync()`. Covers dispatching from widgets via context extensions and from within other actions. --- # Dispatching Actions The foundational principle of AsyncRedux: **the only way to change the application state is by dispatching actions.** You can dispatch from widgets (via context extensions) or from within
npx skillsauth add marcglasberg/async_redux .claude/skills/asyncredux-dispatching-actionsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
The foundational principle of AsyncRedux: the only way to change the application state is by dispatching actions. You can dispatch from widgets (via context extensions) or from within other actions.
The standard method that returns immediately. For synchronous actions, state updates before return; for async actions, the process begins and completes later.
dispatch(MyAction());
Returns a Future that completes when the action finishes and state changes, regardless of whether the action is sync or async. Returns an ActionStatus object.
var status = await dispatchAndWait(MyAction());
if (status.isCompletedOk) {
Navigator.pop(context);
}
Dispatches multiple actions in parallel, returning the list of dispatched actions.
dispatchAll([BuyAction('IBM'), SellAction('TSLA')]);
Dispatches actions in parallel and waits for all to complete.
await dispatchAndWaitAll([
BuyAction('IBM'),
SellAction('TSLA'),
]);
Like dispatch() but throws a StoreException if the action is asynchronous. Use when synchronous execution is mandatory.
dispatchSync(MyAction());
All dispatch methods are available as BuildContext extensions:
context.dispatch(Action());
context.dispatchAll([Action1(), Action2()]);
await context.dispatchAndWait(Action());
await context.dispatchAndWaitAll([Action1(), Action2()]);
context.dispatchSync(Action());
Example button implementation:
ElevatedButton(
onPressed: () => context.dispatch(Increment()),
child: Text('Increment'),
)
For async dispatch in callbacks:
ElevatedButton(
onPressed: () async {
var status = await context.dispatchAndWait(SaveAction());
if (status.isCompletedOk) {
Navigator.pop(context);
}
},
child: Text('Save'),
)
All dispatch methods are available inside actions via the ReduxAction base class:
class MyAction extends ReduxAction<AppState> {
Future<AppState?> reduce() async {
// Dispatch another action and wait for it
await dispatchAndWait(LoadDataAction());
// Dispatch without waiting
dispatch(LogAction('Data loaded'));
return state.copy(loaded: true);
}
}
You can dispatch actions in the before() and after() lifecycle methods:
class MyAction extends ReduxAction<AppState> {
Future<AppState?> reduce() async {
String description = await fetchData();
return state.copy(description: description);
}
void before() => dispatch(BarrierAction(true));
void after() => dispatch(BarrierAction(false));
}
The dispatchAndWait() method returns an ActionStatus object with useful properties:
var status = await dispatchAndWait(MyAction());
// Check completion state
status.isCompleted; // Action finished executing
status.isCompletedOk; // Completed without errors
status.isCompletedFailed; // Completed with errors
// Access error information
status.originalError; // Error thrown by before/reduce
status.wrappedError; // Error after wrapError() processing
// Check method completion
status.hasFinishedMethodBefore;
status.hasFinishedMethodReduce;
status.hasFinishedMethodAfter;
You can also access status directly from the action instance:
var action = MyAction();
await dispatchAndWait(action);
print(action.status.isCompletedOk);
Dispatch methods accept an optional notify parameter (default true) that controls whether widgets rebuild on state changes:
// Dispatch without triggering widget rebuilds
dispatch(MyAction(), notify: false);
| Method | Returns | Waits? | Use Case |
|--------|---------|--------|----------|
| dispatch() | void | No | Fire and forget |
| dispatchAndWait() | Future<ActionStatus> | Yes | Need to know when done |
| dispatchAll() | List<ReduxAction> | No | Multiple parallel actions |
| dispatchAndWaitAll() | Future<void> | Yes | Wait for all parallel actions |
| dispatchSync() | void | N/A | Enforce sync execution |
URLs from the documentation:
data-ai
Show loading states and handle action failures in widgets. Covers `isWaiting(ActionType)` for spinners, `isFailed(ActionType)` for error states, `exceptionFor(ActionType)` for error messages, and `clearExceptionFor()` to reset failure states.
data-ai
Use `waitCondition()` inside actions to pause execution until state meets criteria. Covers waiting for price thresholds, coordinating between actions, and implementing conditional workflows.
testing
Handle user-facing errors with UserException. Covers throwing UserException from actions, setting up UserExceptionDialog, customizing error dialogs with `onShowUserExceptionDialog`, and using UserExceptionAction for non-interrupting error display.
tools
Implement undo/redo functionality using state observers. Covers recording state history with stateObserver, creating a RecoverStateAction, implementing undo for the full state or partial state, and managing history limits.