An NgRx based State Machine for Angular Components

Inspired by articles like the following:
I decided to have a look at what might be involved in creating a Finite State Machine for handling component state in an Angular app we are currently working on. 

As detailed in the above articles, we were finding the use of boolean flags to dictate which state a particular component was in was ok at a very simple level, but as the app grew, and more complex components were added, it didn't scale well. 

What we wanted was a way of components registering a map of valid transitions. Then as actions are emitted they are checked against this map. If valid, the components current state is updated in a special UIState slice of the store and the action is passed trough. If not a valid transition for the given component the action is dropped. For example:
  1. An 'Add Book' component, can be in a state of Idle, Processing, or Errored
  2. An AddBookAction causes it to transition from Idle to Processing. 
  3. This transition is only allowed if the component is currently Idle. If the component is Processing then the transition should be disallowed
My initial thought was to use an NgRx @effect, or a meta reducer to handle the component state transitions. The proof of concept with this approach didn't get far. It is not possible with an @effect or meta reducer to prevent an action propagating further if the dispatched action does not match an allowed transition!

Plan B was to extend the NgRx ActionsSubject. Thanks to the wonders of Angular dependency injection this was relatively easy.


With this in place I just needed to work out how to register the valid component transitions, and how to reflect a components current state back to the UI.  Part 2 looks at the initial approach to registering the state transitions for each component.

Comments