Xstate: Working with action parameters in Vizualizer

Created on 24 Nov 2019  路  6Comments  路  Source: davidkpiano/xstate

馃憢 Hi, I'm new to xstate, so maybe what I'd like trying to do is not the best approach...

Bug or feature request?

probably feature request

Description:

It would be great if you can try actions with parameter in the visualizer

Sample

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

invalid 馃敩 visualizer

Most helpful comment

This is possible in the visualizer already:

Screen Shot 2019-11-24 at 8 12 56 AM

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.

All 6 comments

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:

Screen Shot 2019-11-24 at 8 12 56 AM

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

Was this page helpful?
0 / 5 - 0 ratings