Closed unsay closed 2 weeks ago
Apologies, the Stately link does some sugar and cleans up the machine. To reproduce, see below.
Interestingly, guard: 'functionDoesNotExist'
does what I expect:
Error: Guard 'functionDoesNotExist' is not implemented.'.
While below as a prop on the guards
object resolves truthy.
import { createMachine, createActor } from 'xstate'
const guards = {}
const machine = createMachine({
id: 'testMachine',
initial: 'idle',
states: {
idle: {
on: {
TEST: { target: 'testing' }
}
},
testing: {
always: [
{
target: 'truthy',
guard: guards.functionDoesNotExist
},
{ target: 'falsy' }
]
},
truthy: {
type: 'final'
},
falsy: {
type: 'final'
}
}
})
const actor = createActor(machine)
actor.subscribe({
next: (snapshot) => {
console.log('next:', snapshot.value)
},
complete: () => {
const snapshot = actor.getSnapshot()
console.log('complete:', snapshot.value)
}
})
actor.start()
actor.send({ type: 'TEST' })
The revised code example is working as expected. If a guard is undefined
, then the transition will just be taken. So this:
{
target: 'truthy',
guard: guards.functionDoesNotExist
}
Is essentially the same as this:
{
target: 'truthy'
}
XState version
XState version 5
Description
Given a an undefined function, it seems like the more correct behavior would for the final state to be
falsy
.Expected result
Should there be safeguard check? Or is this by design? It does seem as if the
guard
property is set, it should throw an error as an incomplete guard.Actual result
The
guard
resolves to undefined and is never evaluated, so the firstalways
transition occurs.Reproduction
https://stately.ai/registry/editor/170740c1-7b72-4a23-8066-05571dc51456?machineId=63f824ae-4218-440a-a251-fe25875622e9&mode=design
Additional context
No response