MicheleBertoli/react-automata

Support xstate Machine options parameter

tastywheat opened this issue · 4 comments

I want to add guards as strings (for visualizer compatibility). This requires passing in an object to the Machine function, but it doesn't look like its possible to pass such a configuration into withStatechart.

This is further described here statelyai/xstate#157

const lightMachine = Machine({
  // ...
  states: {
    green: {
	  on: { TIMER: { yellow: { cond: 'someCond' } } }
	}
  }
}, {
  guards: {
	someCond: (xs, e) => /* evaluate condition here */
  }
});

Hey @tastywheat, thanks for opening this issue.

As described in the README:

The withStatechart higher-order component takes an xstate configuration object or an xstate machine [...]

So it's already possible to create a Machine with options and use it with this library.

const SuperComponent = withStatechart(lightmachine)(Component)

I hope this helps.

That sort of helps, but I'm running into an error with the guards not being recognized (I'm not sure if its xstate or react-automata).

Uncaught Error: String condition 'hasResults' is not defined on machine '(machine)'

const machine = Machine({
    "initial": "waiting",
    "states": {
        "waiting": {
            "on": {
                "SEARCH": "searching"
            },
        },
        "searching": {
            "onEntry": "search",
            "on": {
                "SUCCESS": [
                    {
                        "target": "waiting",
                        "cond": "hasResults"
                    }
                ],
            }
        }
    },
}, {
    guards: {
        hasResults: (es, eventObj) => {
            return eventObj.query.items.length > 0;
        },
    },
});

this.props.transition({ 
    type: 'SEARCH',
    query: {
        items: []
    }
})

Hey @brianlawasdf123, I quickly tried your machine:

class App extends React.Component {
  handleSearch = () => {
    this.props.transition({
      type: 'SEARCH',
    })
  }

  handleSuccess0 = () => {
    this.props.transition({
      type: 'SUCCESS',
      query: {
        items: [],
      },
    })
  }

  handleSuccess1 = () => {
    this.props.transition({
      type: 'SUCCESS',
      query: {
        items: [{}],
      },
    })
  }

  render() {
    return (
      <React.Fragment>
        <button onClick={this.handleSearch}>SEARCH</button>
        <button onClick={this.handleSuccess0}>SUCCESS 0</button>
        <button onClick={this.handleSuccess1}>SUCCESS 1</button>
        {this.props.machineState.toString()}
      </React.Fragment>
    )
  }
}

const StateMachine = withStatechart(machine)(App)

And it seems to work:

issue

Do you mind providing more information?
Thank you very much!

Ok, I just reinstalled xstate/react-automata and it works now. Sorry for the inconvenience, but thanks for looking into it.