Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Justin Calleja
    @justin-calleja

    doReadConfig is:

    function doReadConfig() {
      try {
        return readJsonSync(configFilePath);
      } catch (err) {
        if (err.code === 'ENOENT') {
          return 'FileNotFound';
        } else if (isProbablyJSONParseError(err)) {
          return 'JSONParseError';
        }
      }
    }

    its a sync operation - i was advised to split this part up in a separate machine (and for re-usability - it makes sense). If it were async, I'd know how to transition to onError as that would be rejecting the Promise

    I want to invoke readConfigMachine from a parent machine and not handle everything in the parent's onDone. I could do that and then have guards which decide which state to go to after invoking readConfigMachine based on what it returns but it would be cleaner if I could have just one case for success and then transition to onError of the parent for the other cases
    I'll make an example on github which you can run
    David Khourshid
    @davidkpiano
    Lots of messages here :sweat_smile: I'll try to get to them all eventually, but remember you can also create threads on spectrum.chat/statecharts
    Justin Calleja
    @justin-calleja
    ah ok thanks @davidkpiano
    Justin Calleja
    @justin-calleja

    @amitnovick i've uploaded what i started working on here:

    https://github.com/justin-calleja/xstate-examples

    under src/example2

    run with npm i

    node ./src/example2/index.js

    but its a bit of a mess. Don't blame you if you ignore it.

    My question here was:

    "How can I transition to a parent machine's onError? I can transition to onDone via a "final" state but I don't know how to transition to onError. Note: the child Machine performs a synchronous operation. Promises would transition to parent's onError on rejection but I'm not running a Promise so I cannot reject (throwing an Error propagates up and stops the VM)

    Amit Novick
    @amitnovick
    I don't know if it's possible to trigger the onError transition on a parent machine in a state where an invoked service child machine is being executed
    Justin Calleja
    @justin-calleja
    ok thanks @amitnovick . Would you think it would be useful to have this? A Promise can do this so why not a custom Machine?
    David Khourshid
    @davidkpiano
    Send error(invokeId, data)
      actions: sendParent(error(invokeId, data))
    Justin Calleja
    @justin-calleja
    @davidkpiano ah nice thanks!
    David Khourshid
    @davidkpiano
    import { error } from 'xstate/lib/actions' I believe. It's not a root import
    Justin Calleja
    @justin-calleja
    ok cool - yep saw it in the source code (error) but wasn't sure how to use it / if there was a more straightforward way. Do you think a type of "finalError" or something would be a nice addition?
    Amit Novick
    @amitnovick
    Interesting revelation re: error import from xstate/lib/actions.
    Thanks for bringing up this question @justin-calleja and thanks to @davidkpiano for pointing out to the existence of this API.
    Justin Calleja
    @justin-calleja
    @davidkpiano ... i just realised i don't have access to the invokeId. I could make the child Machine creation in a "factory" a function which takes the invokeId and returns the Machine... the "finalError" state type is starting to look very attractive ^^;
    or maybe.. is there a way to get it dynamically?
    (through the current APIs)
    Travis LaDuke
    @laduke
    This message was deleted
    Travis LaDuke
    @laduke

    I have this api that you can get and post to like { bold: true, italic: false }; If I keep bold and italic in context, that's fine;

    I'd maybe like to keep them as parallel states instead, but I don't see a way to then pass that state into a service, so it can post it. hrm. Other than carefully keeping some context in sync with the state?

    Amit Novick
    @amitnovick
    @laduke With parallel states your state.value tracks the values of all the states. Suppose bold, italic both have sub-states of enabled, disabled, then state.value should be an object like:
    { bold: 'enabled', italic: 'disabled' }
    If you need to send it to an API that wants to get true and false values, you can massage that state.value before sending this data to it.
    Travis LaDuke
    @laduke
    Thanks for writing. An invoked service doesn't have access to the state though -that I can see
    Kurt Milam
    @kurtmilam
    Are many folks reusing the same state machines on the front and back ends? My team uses xstate machines on the back end and shares the machine configs with the front end, which has turned out really nicely, so far.
    Travis LaDuke
    @laduke
    that sounds cool
    Kurt Milam
    @kurtmilam
    We use the configs on the front end to control which action-triggering buttons are shown in the UI and use the machines on the back end to make sure a wily user can't craft an API request that bypasses our rules for moving from one state to another.
    You can think of our application as a glorified To-Do application, where we have multiple types of To-Dos. Each type of To-Do has a different set of states through which it can transition (including branches and different final states).
    I've been mulling over the idea of writing an article on the approach. Our team was one of the first to use xstate in our company, and we've been spreading the gospel of xstate to other teams :D
    Shining Condor
    @mcspud_gitlab
    Do it @kurtmilam
    I'm in the middle of a POC to rewrite a banks entire front end app in it
    Kurt Milam
    @kurtmilam
    I think I just might. It's super elegant to be able to reuse the config. Saves a ton of manual work on the front end and keeps the front end in sync with the back end automatically.
    Shining Condor
    @mcspud_gitlab
    That is essentially what I am trying to do now - I just started here but they have implemented a very rudimentary SM using react with URLs, and have gone to extreme lengths to implement behaviour that overwrites a browsers "back" functionality etc to stop it going into invalid states
    Its a mess, so if I manage to get this passed the higher ups I think I'lldo the same
    In the meantime, can you figure out why this parallel machine wont transition to a done state?
    Its infinitely looping
    Kurt Milam
    @kurtmilam
    Cool! Our original plan was just to use it on the back end, but I realized the same config could be used to control a bunch of UI elements. The front end was already asking the back end for a config, so I just rolled up the (slightly transformed) state machine configs and included them in the response. Works a charm.
    Rostero
    @rostero1
    is it possible to send an event to a state machine and have it just update context (no matter where it is) without transitioning? I have something hierarchal now, but it always seems to reset my state
    Shining Condor
    @mcspud_gitlab
    I think you could have the event reference the same state
    on: { MYEVENT: { target: 'Whatever state I'm currently in' }}
    Kurt Milam
    @kurtmilam
    @mcspud_gitlab I wonder whether the discussion in this issue is related to your question: davidkpiano/xstate#437

    btw, this:

      const getOtherContactsAction = async () => await fetch('google.com')

    can be rewritten to this:

      const getOtherContactsAction = () => fetch('google.com')
    Both will return the Promise returned by calling fetch('google.com').

    Also, this:

    const load_contact_details_machine = async() => Promise.resolve()

    Can be rewritten as this:

    const load_contact_details_machine = () => Promise.resolve()
    Kurt Milam
    @kurtmilam
    Also, fetch('google.com') tries to fetch http://xstate.org/google.com, but none of those things are the root of your problem.
    It would be nice if the visualizer had a 'Pause', 'Unload' or 'Interrupt' button to allow you to easily interrupt a loop.
    Shining Condor
    @mcspud_gitlab
    Thanks @kurtmilam , they are just placeholders really,the other code is a bit more verbose
    I'll just run them linearly for now and go from there
    Travis LaDuke
    @laduke
    hrm seems like using an internal transition does reset states
    https://xstate.js.org/viz/?gist=645f066f9b05025d011ee228a6383500
    Travis LaDuke
    @laduke
    ah, only on 4.6, 4.7 doesn't do that