Hi all,
Really love the library! I've a couple of questions regarding guards, actions and reloading of a invoke service.
postNL: {
entry: [{ type: "selectDeliveryMethod", payload: "POSTNL" }],
on: {
SELECT_PICK_UP: "pickUp",
SELECT_DELIVERY: "delivery"
}
}
Is it possible to target a specific state when a guard fails (to let the user know why a specific state is not reachable? Are there other ways to get the same result?
If I use invoke service (promise) on a specific nested state and the parent state changes to something different and comes back to the state, the API request (promise) is invoked. Is there any way to check the context for data before firing again? (not a deal breaker but I'm curious)
Is it possible to call an action in an entry hook with some kind of payload that I can use in the action function to write something to the context.
Yes, for the { type: "selectDeliveryMethod", payload: "POSTNL" } action, the implementation can look like:
// ...
{
actions: {
selectDeliveryMethod: (context, event, { action }) => {
console.log(action.payload);
// => "POSTNL"
}
}
}
Is it possible to target a specific state when a guard fails (to let the user know why a specific state is not reachable? Are there other ways to get the same result?
Yes, if this is what you mean:
{
on: {
SUBMIT: [
{ target: 'submitting', cond: formValid },
{ target: 'invalid' } // <-- default state when guard(s) fail
]
}
}
If I use invoke service (promise) on a specific nested state and the parent state changes to something different and comes back to the state, the API request (promise) is invoked. Is there any way to check the context for data before firing again? (not a deal breaker but I'm curious)
You can use a transient transition 馃摉 to determine which state to go to:
checkForData: {
on: {
'': [
{ target: 'loaded', cond: (ctx) => ctx.data !== undefined },
{ target: 'loading' }
]
}
},
loading: {
invoke: { /* ... */ }
},
loaded: {}
Wow thanks! This will help me a awful lot!
Okay I can't seem to get usecase 1 working, tried a couple of things but how do I get access to the action variable inside the assign function?
selectDeliveryMethod: (_, __, action) => assign({
selectedDeliveryMethod: (context, event) => {
console.log(context, event, action);
return " ssss";
}
This does not seem to work and there is no action variable inside the assign function.
PS I don't really get why I can't return assign() from a other function.
One limitation of assign() right now is that it only gets the context and event. For now, one approach/workaround that I'd recommend is to just use JS:
function assignDeliveryMethod(payload) {
return assign({ deliveryMethod: payload });
}
// ...
{
actions: assignDeliveryMethod('POSTNL')
}
PS I don't really get why I can't return assign() from a other function.
You can; that's what the above pattern is doing.
Okay just so I'm sure I understand correctly: there is no way to combine a state (to use state.matches) argument with the assign function? Can I add the feature request if there isn't already one to add the meta argument to the assisgn function?
Okay just so I'm sure I understand correctly: there is no way to combine a state (to use state.matches) argument with the assign function? Can I add the feature request if there isn't already one to add the meta argument to the assisgn function?
Could you describe what you are trying to do in more detail?
@davidkpiano You mentioned that
One limitation of assign() right now is that it only gets the context and event.
Would it be possible in the future to access state meta information inside assign function?
I'm trying to collect meta data from all the states that were passed in one event. Specifically add meta messages to context message array.
Would it be possible in the future to access state meta information inside assign function?
Yes, it will.
Closing this as assigners/property assigners do get the state meta information:
export interface AssignMeta<TContext, TEvent extends EventObject> {
state?: State<TContext, TEvent>;
action: AssignAction<TContext, TEvent>;
_event: SCXML.Event<TEvent>;
}