-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conditional actions #990
Comments
I normally have "decision point" states with Transient Transitions. All the conditions go in that state which leaves the states with so each action in your I see |
SCXML precedent: https://www.w3.org/TR/scxml/#if |
From #1036 just for visibility and potential discussion. Or, to put it in perspective: on: {
"": [
{ target: "x", condAction: (context) => context?.x ? send({ type: "x", x: context.x }) : false },
{ target: "y", condAction: (context) => context?.y ? sendParent({ type: "y", y: context.y }) : false },
{ target: "z", condAction: (context) => context?.z ? assign({ z: context.z + 1 }) : false },
...
]
} For reasoning and examples check out the linked issue. |
@MrNovado There is an undocumented (because it's experimental) import { pure } from 'xstate/lib/actions';
// ...
on: {
'': {
actions: pure(ctx => {
return ctx.x ? send(/* ... */)
: ctx.y ? sendParent(/* ... */)
: ctx.z ? assign(/* ... */) : undefined;
})
}
} Let me know if that satisfies your needs! |
@davidkpiano playing with it for a while, I realized conditional-actions, while cool and should definitely exist, is not the thing I actually wanted. I want a simpler way of declaring a transition. Made another issue for it here #1038; hopefully, explained myself better this time.
|
A draft implementation is available here: #1076 |
@Andarist @davidkpiano Thank you for implementing // impl with one action
// reuses the form of our existing function, just exit points replaced with `raise()`
onError: {
target: 'failure', // TODO or retry?
actions: (_, { data: err }) => {
// Runtime error
if (!(err instanceof SomeError)) {
throw err
}
let shouldRetry
switch (err.type) {
case FAILURE_REASON_A:
return raise(FAILURE_REASON_A)
case FAILURE_REASON_B:
case FAILURE_REASON_C:
case FAILURE_REASON_D:
return raise('RETRY')
default:
return raise('FAILURE')
}
},
},
// impl with choose()
onError: {
target: 'failure',
actions: choose([
{
// Runtime error
cond: (_, { data: err }) => !(err instanceof SomeError),
actions: (_, { data: err }) => throw err,
},
{
cond: (_, { data: err }) => err.type === FAILURE_REASON_A,
actions: raise(FAILURE_REASON_A),
},
{
cond: (_, { data: err }) =>
[FAILURE_REASON_B, FAILURE_REASON_C, FAILURE_REASON_D].includes(err.type),
actions: raise('RETRY'),
},
{
actions: raise('FAILURE'),
},
]),
}, By the way, I'm not sure if the |
|
Hello @Andarist 👋🏽 eg: actions.ts const someCoolAction = pure<[how to type this properly]>(() => assign(....)) coolMachine.ts import * as actions from "./actions"
export const coolMachine = createMachine(
....
tsTypes: {} as import('./coolMachine.typegen').Typegen0,
....
actions: {
someCoolAction: actions.someCoolAction,
}
|
I think the possibility of conditional actions should be entertained, similar to guarded transitions:
The text was updated successfully, but these errors were encountered: