馃憢 Hi, I'm new to xstate, so maybe what I'd like trying to do is not the best approach...
probably feature request
It would be great if you can try actions with parameter in the visualizer
I have such a simple state machine, which should let you add numbers until context count is 10:
const sumToTenMachine = Machine({
id: "summer",
initial: "counting",
context: {
count: 0
},
states: {
counting: {
on: {
ADD: [
{
cond: (context, { no }) =>
no > 0 && context.count + no <= 11,
actions: assign({
count: ({ prevCount }, { no }) => prevCount + no
})
},
{
target: "success",
cond: (context, { no }) => context.count + no === 10,
actions: [
assign({
count: ({ prevCount }, { no }) => prevCount + no
})
]
}
]
}
},
success: {
type: "final"
}
}
})
But if I'd like to try it in the visualizer, it is not possible (or I don't know how to do it) because I cannot specify "count" param in the visualizer
This is indeed somewhat a problem with how visualizer works now. This particular case is broken because visualizer classifies both as invalid transitions - in a sense that their guard cannot be satisfied at the moment.
https://github.com/statecharts/xstate-viz/blob/9c50ad32497e36b46b34031962372a5427af2b2f/src/StateChartNode.tsx#L641-L648
One of the problems I see there is that guards are being eagerly evaluated with current.event - but this is not the event they should be tested with, in a real app. Those guards should be evaluated with "future" events - which is of course impossible. Seems like we should rethink how we handle guards in the viz in general.
This is possible in the visualizer already:

Also, your logic will always take the first condition, because even when event.no === 10, the first condition will pass, and it will never transition.
Thanks for a quick response, I updated it like below and it looks it works fine.
const sumToTenMachine = Machine({
id: "summer",
initial: "counting",
context: {
count: 0
},
states: {
counting: {
on: {
ADD: [
// order is important
{
target: "success",
cond: (context, { no }) => context.count + no === 10,
actions: [
assign({
count: ({ count: prevCount }, { no }) =>
prevCount + no
})
]
},
{
cond: (context, { no }) =>
no > 0 && context.count + no <= 11,
actions: [
assign({
count: ({ count: prevCount }, { no }) =>
prevCount + no
}),
actions.log(
(context, event) =>
`count: ${JSON.stringify(context)}, event: ${
event.type
} payload: ${event.no}`,
"ADD"
)
]
}
]
}
},
success: {
type: "final"
}
}
})
@davidkpiano there is still an issue of guards being evaluated against wrong events
@Andarist That's probably a separate issue
@Andarist I try to address it in https://github.com/statecharts/xstate-viz/pull/47
Most helpful comment
This is possible in the visualizer already:
Also, your logic will always take the first condition, because even when
event.no === 10, the first condition will pass, and it will never transition.