Frontend is Rocket Science – Managing state in any JavaScript Application

In this Blogpost, we will talk about the xState JavaScript library for managing state in any Frontend Framework.

Most of the time our Web Applications or Websites represent some kind of state. It can be Server State or UI State. It can be finite or infinite.

The infinite state is the data we get from the server. For Example a User Object. It is infinite because it can hold an infinite amount of information, like first name, last name, address, tokens, subscriptions, and so on. We can’t count this state. On the other side, we have a finite state like signed in or signed out, is user account blocked or not. It can also hold information about the loading states like is the user currently logging in registering or logging out. Or maybe the user of the website tries to update his profile, and we need to show the user when he clicks on the button save, that his action was successful or not.

From now on I will use this emoji to represent state names:
⏳ loading
πŸ†˜ failed
βœ… success

These are 3 typical states of the JavaScript Promise.

If I would represent this logic with boolean values I’ll lose control pretty quickly and I might end up in a state which should never exist.
Let’s see what will happen if we use BBooleans to represent our small application State.

ok we do nothing so all the states are false
⏳ false πŸ†˜ false βœ… false

now we press the button to load and it is loading something
⏳ true πŸ†˜ false βœ… false

we are still loading and we got the data back
⏳ true πŸ†˜ false βœ… true this state should not be possible, we need to set ⏳ to false before we set the βœ… to true
⏳ false πŸ†˜ false βœ… true

if we get an error we should do the same
⏳ true πŸ†˜ true βœ… false is impossible
⏳ false πŸ†˜ true βœ… false should be the correct one

So it means whenever we set the loading(⏳) state to true none of the other states(πŸ†˜βœ…) can be true

In total, we will have 8 States 3 to the power of 2. This is a very simple example with only 3 variables, imagine we would have 4 or more. It will be almost impossible to avoid mistakes and set all the booleans in the right moment.

This problem is well known in software and math and it is called Combinatorial ExplosionΒ 
Or this video explains it well based on infections and virus spread

Now let’s list all possible states we might have, give them names and mark those which we don’t need

⏳ false πŸ†˜ false βœ… false = idle
⏳ false πŸ†˜ false βœ… true = success
⏳ false πŸ†˜ true βœ… false = failed
⏳ false πŸ†˜ true βœ… true = not possible
⏳ true πŸ†˜ false βœ… false = loading
⏳ true πŸ†˜ false βœ… true = not possible
⏳ true πŸ†˜ true βœ… false = not possible
⏳ true πŸ†˜ true βœ… true = not possible

So from 8 States we only care about 4: idle, success, failed, and loading

Now let’s create a JavaScript object with names for the keys instead of

const logic = {
	states: {
		idle: {}
		loading: {}
        	success: {}
		failed {}
	}
}

Now we have only the states we care about and not a boolean soup we had previously. We miss only one part and it is: How do we know in what state we are currently in.

The first naive approach would go back to booleans and write something like idle: true or false, but we don’t want to back to booleans because we know what troubles it can create.

We will create another key on our logic object and call it current. It will hold the state, we are in, during the execution of our program.

const logic = {
	current: 'idle'
	states: {
		idle: {}
		loading: {}
        	success: {}
		failed {}
	}
}

In our boolean example, it was not clear how we go from one state to another it was completely hidden in the code implementation. And usually, if we would come back to this code 3 months later we would need to recreate the mental model of the program in our head before we can make any change to the code.

In our logic object, we can define transitions between states. How we can go from one state to another. We can even visualize the logic by drawing boxes for our states and arrows between the boxes which will represent the transitions. This is called a state transition diagram. This is very because you can see how the program executes in real-time (about this I will write in my future blogposts)

Screenshot 2020-12-11 at 13.48.44
const logic = {
	current: 'idle',
	states: {
		idle: {
        		on: {
          			load: "loading"
        		}
      		},
      		loading: {
        		on: {
          			onDone: 'success',
          			onError: 'failed'
        		}
      		},
      		success: {},
      		failed: {}
	}
}

Now it is very clear how our Program, let’s call it a machine, works from now on. We have described all possible states in the machine, all transitions from one state to another, and eliminated all impossible states.

Some more random facts about State machines and Statecharts

What if I tell you that this technique is not new it is even older than ME and it is used everywhere. Electronics, Airplanes, Games, and Even Space Rockets and Spaceships. The famous Curiosity’s Rover which is on planet mars was programmed like this. It was the most successful NASA mission ever. And they had only ONE deployment.

Not many people know thatΒ xState is JavaScriptΒ  the implementation for W3C Specification State Machine Notation for Control Abstraction

It is well suited for small and huge programs. It scaled very well thanks to the Actor model and it makes your application very robust

Here the video below you can see the full implementation of our logic. Logic from the video and our code in this article is almost the same.

Here is also a short video, where I live code this example at Vue Toronto 2020 ConferenceΒ Have fun watching.

Life coding is very exiting and I did many mistakes πŸ˜€ but it worked in the end

No Thoughts to Frontend is Rocket Science – Managing state in any JavaScript Application

Leave a Reply