Rule Over Your Angular2 State Machine

Handle your Angular 2 application state better and make your frontend developer life that much easier.

photo of Vadym Kukhtin
Vadym Kukhtin

Frontend Developer

Posted on Jan 18, 2017

It is really important to control your application state. Extremely important. The application state binds all of your functionality together, allowing us to do the awesome things we love about programming.

Today I want to write about the Angular2-state-machine, which helps you handle your Angular 2 application state and, hopefully, makes your life as a developer much easier.

The state-machine is an Angular 2 port of Jake Gordon’s javascript-state-machine, with small changes made according to the Angular 2 TypeScript specification. It was created for small state-machines like page statuses in CMS: Draft -> In Process -> In Review -> Reviewed -> Published.

You can use it as a main state-machine for whole application state manipulation, however it is my opinion that Redux handles large state-machines better. This small library was created for easy, smooth states, rather than bigger state manipulation points (like Redux).

Documentation

First of all let’s install the library using NPM:

npm i angular2-state-machine --save

As an example, let us attempt to create an app that will handle traffic lights.

Assume you already have a basic Angular2 app and you want to insert the state-machine:

import {StateMachine, StateEvent} from 'angular2-state-machine/core';
let fsm = new StateMachine({
    initial: 'green',
    events: [
        new StateEvent({
            name: 'toGreen', from: ['yellow'], to: 'green'
        }),
        new StateEvent({
            name: 'toRed', from: ['yellow'], to: 'red'
        }),
        new StateEvent({
            name: 'toYellow', from: ['red', 'green'], to: 'yellow'
        })
    ]
});

You can see that we’ve used the terms StateMachine and StateEvent above. StateMachine is a service itself which handles states, whereas StateEvent is a typed object which stores information about state and transitions.

We’ve created a state-machine that consists of three traffic light states: Green, Yellow, and Red, and we’ve established transition names from one to the other: ‘toGreen’, ‘toYellow’, ‘toRed’.

We must only use unique transition names or the service will throw an Error: “You have to use unique names for all events”.

The traffic lights in our app will start from the color Green and after some time we must change the light to Yellow:

fsm.fireAction('toYellow'); // Now we’ve changed the state-machine current state from green to yellow

To be sure, we can run ‘getCurrent()’:

fsm.getCurrent() // Yellow

For some use cases, such as huge state amounts or some tricky logic, you must be able to check whether you’re able to move from this state to another state. Voila! You can use ‘can’ and ‘cannot’:

fsm.can('toYellow') // Error 'You cannot switch to this state' because it is already yellow

With cannot:

fsm.cannot('toYellow') // true

You can also access all transition names which are available to you:

fsm.getEvents() /*  [StateEvent({
            name: 'toGreen', from: ['yellow'], to: 'green'
        }),
        StateEvent({
            name: 'toRed', from: ['yellow'], to: 'red'
        }),
        StateEvent({
            name: 'toYellow', from: ['red', 'green'], to: 'yellow'
        })
    ]*/

As well as get all available transitions names:

fsm.getTransitions() // 'toYellow'

Or go back to the previous state:

fsm.goToPreviousState() // 'green'

And that’s ALL! With simplicity and ease, you can handle your state to help your app to shine brightly.

I would really appreciate any comments or feedback on this information or the library itself, and hope it helps to tackle your states. You can find me on Twitter at @vadkuhtin for feedback, or head directly to GitHub here. The NPM package can be found here.



Related posts