DEV Community

Cover image for Starting with State Machine and Xstate!
Jasmin Virdi
Jasmin Virdi

Posted on

Starting with State Machine and Xstate!

As a software developer, we all must have heard about state machines at some point in time. A finite state machine is pretty famous in designing algorithms like calculating the output on the basis of the series of inputs or calculating the next state based on the output from the current and previous states.

There are many popular examples of state machines which you must have heard.

  • Traffic Lights 🚦
  • Vending Machine βš’οΈ
  • An Elevator πŸšͺ

Since the state machine is a very compact way to represent a set of complex rules and conditions so let's find out how we can extend its use in our frontend applications.

Why do we need State Machine on Frontend?

State management in the browser has always been a tricky part, especially when working on large applications that have complex state management. The UI framework has a major role to take our application state and turn it down to the DOM node for achieving the desired result.

State Machine is a very useful way of modeling states in an application such that the application can be in only one state at any given point of time. All these benefits will help us to solve issues related to the scaling of our applications which eventually requires new events, new corner cases, etc.

Starting with our Application.

Let's begin by creating a simple Todo Application in Vue.js using Xstate.

The first step is to determine all the possible UI states needed to create a TodoList. I began jotting down the basic states and actions which are required for the application.

  • There will be some basic states like idle, loading, resolved, rejected

  • Set of actions required in the application will be update list, create new todo item, update a todo item and delete a todo item

  • The edit, delete and create will be parallel states as the user can perform all the three actions simultaneously.

Using the above pointers I have created a basic state chart on Xstate Viz covering all the states and actions of my application.

Alt Text

The state machine definition code:

Machine(
  {
    id: 'Todo',
    initial: 'idle',
    context: {
      user: null,
      todoList: [],
      delay: 0
    },
    states: {
      idle: {
        on: {
          fetch: 'list'
        }
      },
      list: {
        invoke: {
          id: 'fetchList',
          src: (context, event) => {
            return context.todoList
          },
          onDone: {
            target: 'resolved'
          },
          onError: 'rejected'
        },
        on: {
          listItems: {
            target: 'todoItemActions',
            actions: 'addListItem'
            //   actions: ['fetchListItems']
          }
        }
      },
      resolved: {
        type: 'final'
      },
      rejected: {
        on: {
          fetch: 'list'
        }
      },
      todoItemActions: {
        type: 'parallel',
        states: {
          createTodoItem: {
            initial: 'add_details',
            states: {
              idle: {
                on: {
                  create: 'add_details'
                }
              },
              add_details: {
                on: {
                  fillDetails: {
                    target: 'createSuccess',
                    actions: 'createNewTodoItem'
                  }
                }
              },
              createSuccess: {}
            }
          },
          deleteTodoItem: {
            initial: 'idle',
            states: {
              idle: {
                on: {
                  select_item: 'deleteItem'
                }
              },
              deleteItem: {
                on: {
                  delete: {
                    target: 'deleteSuccess',
                    actions: 'deleteTodoItem'
                  }
                }
              },
              deleteSuccess: {}
            }
          },
          editTodoItem: {
            initial: 'idle',
            states: {
              idle: {
                on: {
                  edit: 'edit_details'
                }
              },
              edit_details: {
                on: {
                  fill_details: {
                    target: 'editSuccess',
                    actions: 'editTodoItem'
                  }
                }
              },
              editSuccess: {}
            }
          }
        }
      }
    }
  },
  {
    actions: {
      createNewTodoItem: (context, event) => {
        console.log('create new todo item', context)
      },
      addListItem: (context, event) => {
        console.log('add list item', context, event)
      },
      deleteTodoItem: (context, event) => {
        console.log("delete todo item", context, event)
      },
      editTodoItem:  (context, event) => {
        console.log("edit todo item", context, event)
      }
    }
  }
)
Enter fullscreen mode Exit fullscreen mode

You can check the above state machine definition on Visualizer

In the next post, I will be covering the integration and creation of the Todo App using Xstate in Vue js.

There are few awesome articles on the web from where I got the inspiration, do check them out!πŸ™ˆ

Latest comments (4)

Collapse
 
vaibhavkhulbe profile image
Vaibhav Khulbe

Nicely written!

Collapse
 
jasmin profile image
Jasmin Virdi

Thank you!

Collapse
 
davidkpiano profile image
David K. 🎹

This is awesome, looking forward to the next post!

Collapse
 
jasmin profile image
Jasmin Virdi

Thank you so much, I really enjoyed working on Xstate. It is super amazing! πŸ˜ƒ