1

As title implies, I have a guarded transitions that I wanted to be in a Hierarchical State Node, however it seems that xState can not read property of guards and returns a "TypeError: Cannot read property 'propertyName' of undefined" error"

Is there a way to do this in xState, or should I proceed without hierarchical State Node in this case

2 Answers2

2

Right so issue I was having was that i had context assigned to my hierarchical state machine instead of the parent machine, so guards couldn't access it. Moving context to the parent machine has solved the issue

1

I used the hierarchical state machine example from the docs to try and model this, adding the following in the tail end of the example:

    on: {
      POWER_OUTAGE: '.red.blinking',
      POWER_RESTORED: '.red',
      POWER_TEST: {
        target: '.red.stop',
        cond: {
          type: 'test'
        }
      }
    }
  },{
    guards: {
      test: () => true
    }
  });

This seems to work as expected, you can try this machine and guard example in the visualizer here

You can flip the boolean in the test guard to play around with it working/not working.

And here is the complete code of the example for reference:

const pedestrianStates = {
    initial: 'walk',
    states: {
      walk: {
        on: {
          PED_COUNTDOWN: 'wait'
        }
      },
      wait: {
        on: {
          PED_COUNTDOWN: 'stop'
        }
      },
      stop: {},
      blinking: {}
    }
  };

  const lightMachine = Machine({
    key: 'light',
    initial: 'green',
    states: {
      green: {
        on: {
          TIMER: 'yellow'
        }
      },
      yellow: {
        on: {
          TIMER: 'red'
        }
      },
      red: {
        on: {
          TIMER: {
            target: 'green',
            cond: {
              type: 'searchValid'
            }
          }
        },
        ...pedestrianStates
      }
    },
    on: {
      POWER_OUTAGE: '.red.blinking',
      POWER_RESTORED: '.red',
      POWER_TEST: {
        target: '.red.stop',
        cond: {
          type: 'test'
        }
      }
    }
  },{
    guards: {
      test: () => true
    }
  });
TameBadger
  • 1,580
  • 11
  • 15
  • Thank you very much for the answer. Unfortunately I am trying to have guards within the hierarchical state. while your example has the guards outside of it. I should have been more descriptive. Sorry about that. – Giorgi Guledani Jan 30 '20 at 11:44