Xstate: Question - multiple invoke

Created on 22 Jan 2019  路  4Comments  路  Source: davidkpiano/xstate

Actions and Activities can be launched in a sequence, for example specifying ['doThing1', 'doThing2'] as a state's actions.

However, it isn't clear how or if invoke() can be called multiple times in a state, for example to set different Promises off when the state is entered.

documentation question

All 4 comments

You can invoke multiple services by specifying them as an array:

{
  invoke: [
    { id: 'svc1', src: ... },
    { id: 'svc2', src: ... }
  ]
}

@davidkpiano: This is a followup question so I add that here. Is there a way to wait till all invoked services have reached their final state before moving on to the next state?
In the example below I'd like all childMachines be in their final state before moving on to the success state. Putting target: "success" into the onDone configuration doesn't do the job as the first response will move to success ignoring all other responses that are still in flight.

states: {
    pending: {
      invoke: [
        {
          id: "topTenProjects",
          src: topTenProjects,
          onDone: {
            // target: "success",
            actions: assign((ctx, event) =>
              produce(ctx, draft => {
                draft.topTenProjects = event.data
              })
            )
          }
        },
        {
          id: "fundingTypes",
          src: fundingTypes,
          onDone: {
            // target: "success",
            actions: assign((ctx, event) =>
              produce(ctx, draft => {
                draft.fundingTypes = event.data
              })
            )
          }
        }
      ]
    },
    success: {}
  }

@RainerAtSpirit That would probably make a good new issue. I haven't seen anything in SCXML that would notify "when all invoked services are done" although you can accomplish this with "when all parallel states are done" - https://xstate.js.org/docs/guides/final.html#parallel-states

That might be a bit verbose, but it's for good reason - parallel states can have invoked services on each of them, but they can also be normal states without invoked services.

You can create a helper function that cuts down on the extra config, something like:


states: {
  pending: {
    ...parallelServices(svc1, svc2, svc3),
    onDone: { /* ... */ }
  }
}

Was this page helpful?
0 / 5 - 0 ratings