xstate
xstate copied to clipboard
`state.matches` support for custom state IDs
Description
I'm really enjoying custom state IDs, as my state hierarchy is very nested. They work great for the target: "#some_specific_state"
use case.
I was expecting state.matches("#some_specific_state")
to work, too, but it always returns false even if the machine is in that state.
I tested this by doing some console.log
debugging inside of a custom guard:
guards: {
templatesNotLoading: (_ctx, _e, { state }) => {
console.log(`checking state: ${JSON.stringify(state)}`);
console.log(`matches? ${state.matches("#templates_loading")}`);
console.log(`matches!!? ${state.matches(
"form_open.catalog_and_template_selection.template_selection.data_not_loaded.loading"
)}`);
return !state.matches("#templates_loading");
}
},
I confirmed that I do have the custom ID defined correctly on the relevant node:
loading: {
id: "templates_loading",
...
}
Expected result
In the example above, I expect both console.log
s to print true
when the machine is in the templates loading state.
Actual result
The one with the absolute path prints true, but the one with the custom ID reference prints false.
Reproduction
Not readily available at the moment
Additional context
I'm using XState 4.32.1.
This would be more of a feature than a bug. You can do this manually now:
function matchesId(state, id) {
return !!state.configuration.find(stateNode => stateNode.id === id.slice(1));
}
matchesId(state, '#templates_loading'); // true or false
Agreed -- this would be a nice to-have.
I like your helper function - I'll give that a try!
Works like a charm :100:
Closing this as it has a sensible workaround, and we likely don't want to introduce an additional helper function for this.
We may reconsider if it is a more common use-case that is desired for state.matches(...)
.
Also, note that tags
can also be a feasible approach:
loading: {
id: 'templates_loading',
tags: ['loading']
}
// ...
state.hasTag('loading'); // true or false