I have an xstate state machine that has 3 states, idle, waitingForA and waitingForB. waitingForB, in turn is a type of parallel state. I would like to return to initial state of 'idle' on waitingForB is done. How do I accomplish this?
idle: {
id: 'initialState'
},
waitingForA: {
invoke: { /*Promise*/ },
onDone: { target: 'idle' },
onError: { alert(); }
},
waitingForB: {
type: 'parallel',
states: {
waitingForC: {
invoke: { /*Promise*/ },
onDone: {
target: 'success',
actions: assign({ CreturnCode: (context, event) => event.data, })
}
},
waitingForD: {
invoke: { /*Promise*/ },
onDone: {
target: 'success',
actions: assign({ DreturnCode: (context, event) => event.data, })
}
},
success: {
// here, I would like ot go back to initial state of 'idle'
// based on both CreturnCode and DreturnCode
}
}
}
I assume you want to transition out of the parallel state
waitingForBinto theidlestate once both promiseCandDare done.There are two ways to accomplish this behavior:
1. Using
Promise.all()to wrap both promises in theall()function.Using
Promise.all()(mdn docs), you can get rid of the parallel state altogether. Instead, you would only have a normal state called sth. likewaiting For C and Dthat invokes both promises at once withPromise.all([promiseC, promiseD]).2. Transitioning both child states of the parallel state into their own final state.
In your case, the parallel state has two nested states which each invoke a promise. When the promise of a nested state is resolved, you can use the
onDoneevent to transition the nested state to a final state. Once both nested states have transitioned to their respective final state, anonDoneevent is automatically raised for the parallel state. There you can define a transition to theidlestate of the parent machine.Here is an example by Matt Pocock using the second approach.