Skip to content

How to work with "state"? #522

Open
Open

Description

@MichalBryxi

Hi,

I can see that for xstate matches there is a shorthand in ember-statechart-component:

<Toggle as |toggle|>
  (toggle.matches 'inactive')
</Toggle>

From the official xstate documentation it seems like it should also work in this way:

<!-- This does not work -->
<Toggle as |toggle|>
  (toggle.snapshot.matches 'inactive')
</Toggle>

But this does not work with:

Uncaught TypeError: Cannot read properties of undefined (reading 'value')

And respective this(?) is there set to undefined:

Screenshot 2024-12-22 at 17 33 54
(screenshot tests step1, but it's supposed to be inactive in the example above)

I came to this conclusion from an ability to access context on snapshot which works for me:

<Toggle as |toggle|>
  {{toggle.snapshot.context.isActive}}
</Toggle>

I do not necessarily care about how do I call state.matches as there is a way, but I wanted to access state.can and possibly other functions, but it does not work for me.

Activity

  1. NullVoxPopuli commented on Dec 22, 2024

    @NullVoxPopuli
    Owner

    aye, that's a bug with glimmer-vm, which (when fixed) will also unlock: emberjs/rfcs#1045

  2. NullVoxPopuli commented on Dec 22, 2024

    @NullVoxPopuli
    Owner
  3. tcjr commented on Apr 8, 2025

    @tcjr

    I do not necessarily care about how do I call state.matches as there is a way, but I wanted to access state.can and possibly other functions, but it does not work for me

    I ran into this same problem trying to use tags. It seems like you should be able to do something like this:

    <Toggle as |toggle|>
      {{if (toggle.snapshot.hasTag "on") "ON" "not ON"}}
    </Toggle>

    But this doesn't seem to work for me. I worked around it by creating a helper function and doing it in JS:

    const hasTag = (x, tag: string) => {
      return x.snapshot.hasTag(tag);
    };
    <Toggle as |toggle|>
      {{if (hasTag toggle "on") "ON" "not ON"}}
    </Toggle>

    I tried can, and it will work as well:

    const can = (x, eventType: string) => {
      return x.snapshot.can({ type: eventType });
    };
    <Toggle as |toggle|>
      {{if (can toggle "TOGGLE") "can toggle" "cannot toggle"}}
    </Toggle>

    So it works, but these (and a couple other little things) are just enough friction to have me going back to using xstate directly instead of the component.

  4. NullVoxPopuli commented on Apr 8, 2025

    @NullVoxPopuli
    Owner

    yea, sorry I haven't fixed the VM yet :(
    waiting on some syntax changes in glimmerjs/glimmer-vm#1690

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions