Resolving XState Issues: Follow-Up and Solutions

After writing about my XState struggles, the lead developer contacted me with helpful clarifications. With his guidance, I was able to fix all my issues in one day.

This was the most helpful part of his post:

Definitely. One of the most common gotchas is this:

ts entry: () => { assign(...); // assign is not imperative! }

Action creator functions create "action objects" that look like { type: 'xstate.assign', ... } that XState then interprets. But as they're functions (factory functions really), this isn't intuitive at all.

This is why my actions were not working.


// this works - raise is a factory function
action: [raise({type: "success"})]

// this is not equivalent, and does not work
action: ['raiseSuccess']
raiseSuccess: function () => { raise({type:"success"}) }

The second issue is that my syntax for actions was wrong.

// does not work
({ event, context }) => assign({ someValue: event.value || context.value });

// this is correct
assign(({ event, context }) => ({
  pollingRateDelayInMS: event.output || context.pollingRateDelayInMS,
}));

Finally, I read more about the assertEvent helper function. Implementing a few fixed all of my typescript errors inside the state machine.

exit: [
  {
    type: "logError",
    params: ({ event }) => {
      assertEvent(event, "REQUEST_SUBSCRIPTION");
      logError(event); // properly typed now
    },
  },
];

I'd like to express my sincere gratitude to the XState lead developer for reaching out and providing invaluable insights.