onDone: transition when actor completes

If the request is successful we want to transition to a new "Complete" state. We achieve this from onDone inside invoke:

const machine = setup({
  types: {
    context: {} as Context,
    events: {} as Event,
  },
  actors: { submitActor },
}).createMachine({
  context: initialContext,
  initial: "Editing",
  states: {
    Editing: {
      on: {
        "update-username": {
          actions: assign(({ event }) => ({
            username: event.username,
          })),
        },
        submit: { target: "Loading" },
      },
    },
    Loading: {
      invoke: {
        src: "submitActor",
        input: ({ event, context }) => {
          assertEvent(event, "submit");
          return { event: event.event, context };
        },
        onDone: { target: "Complete" },
      },
    },
    Complete: {},
  },
});

onDone is executed when the Promise inside the submitActor resolves successfully.

With this the machine logic is complete. Let's recap:

  • Define a separate submitActor that executes an async request
  • Reference submitActor inside setup/actors
  • Add a submit event to the "Editing" state that transitions to "Loading"
  • Add invoke inside the "Loading" state to execute the submitActor
  • Pass the input to the submitActor inside invoke/input
  • When the submitActor finishes successfully transition to "Complete"