Giggle With Deterministic Finite State
X-State: A better way to manage state.

Search for a command to run...
X-State: A better way to manage state.

Great article! I think using <q-icon> instead of <svg> in the code snippets might make it easier to read them.
Thanks Samuel Leishman. We edited it to make it more readable as you proposed.
Email solved the attachment problem of 1992. Your 4K video deserves a better way to travel.

The file is six feet away. Why does the software behave as if you are opening a bank account?

You are handing over the keys to your entire digital life just to send a single PDF. And it’s time to stop.

What our first week actually showed—and what it did not prove.

This is why we built SEYFR: you deserve to stay in charge of your most important files.

Recently, at our company, candidates were given a seemingly trivial but exciting challenge related to state management.
A light bulb can only be in 1 of 3 finite states at any time. Once broken*, it can neither be* lit nor unlit*. Write a Vue component that accurately represents such a light bulb.*
If You Have a Hammer, Everything is a Nail. it’s very tempting to rush into such an exercise with conditional statements shouting "hoo·ray, I know my booleans." That's exactly what Joanne did. She came out of that interview room very optimistic. And this is what her code looked like.
<div class="container mx-auto column items-center">
<q-btn v-if="broken" fab color="dark" icon="fas fa-lightbulb"/>
<div v-else>
<q-btn v-if="!isLit" fab color="dark" icon="fas fa-lightbulb"/>
<q-btn v-else fab color="orange" icon="fas fa-lightbulb" />
</div>
<div class="row justify-center q-gutter-md">
<q-radio v-model="isLit" :val="true" label="Lit" />
<q-radio v-model="isLit" :val="false" label="Unlit" />
<q-radio v-model="broken" :val="true" label="Broken" />
</div>
</div>
</template>
<script setup>
import { ref, watch } from "vue";
let broken = ref(false);
let isLit = ref(false);
watch(
// If broken its definitely unlit
() => broken.value,
(newVal) => {
if (newVal) {
isLit.value = false;
}
}
);
watch(
// If it's lit it can not be broken
() => isLit.value,
(newVal) => {
if (newVal) {
broken.value = false;
}
}
);
</script>
Wow! This is a handful of booleans. But the challenge is, when *broken**, Joanne's bulb is still unlit and can still be lit.
Andrew on the other hand was a little bit careful, he understood that the bulb in question was supposed to be in exactly 1 of 3 (a finite number of) states at any given time and decided that the variable in each instance was the state of the bulb. For starters, the state of a component is the internal private data (usually an object) that holds information representing the behavior of that component at that instance that may change over the lifetime of the component. Anyway, Andrew's code looked like this:
<template>
<div class="container mx-auto column items-center">
<q-btn
fab
color="dark"
icon="fas fa-lightbulb"
v-if="state === 'broken'"
/>
<div v-else>
<q-btn
fab
color="dark"
icon="fas fa-lightbulb"
v-if="state === 'unlit'"
/>
<q-btn
fab
color="orange"
icon="fas fa-lightbulb"
v-if="state === 'lit'"
/>
</div>
<div class="row justify-center q-gutter-md">
<q-radio v-model="state" val="lit" label="Lit" />
<q-radio v-model="state" val="unlit" label="Unlit" />
<q-radio v-model="state" val="broken" label="Broken" />
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
let state = ref("unlit");
</script>
Surely Andrews' approach was more meticulous. At any instance, his bulb will either be lit, unlit or broken. The challenge is, when broken, it can still be lit or unlit at a later point in time.
Without further adieu, let me tell you who won. Diane; knew precisely what the right tool for the job was. X-State! First, she used X-State's Visualizer to design a lightbulb state machine as shown below:
The tool automatically generated the javascript code below which represents the lightbulb finite state machine
import { createMachine } from "xstate";
export default createMachine({
predictableActionArguments: true,
initial: "unlit",
states: {
unlit: {
on: {
BREAK: {
target: "broken",
},
TOGGLE: {
target: "lit",
},
},
},
broken: {
type: "final",
},
lit: {
on: {
BREAK: {
target: "broken",
},
TOGGLE: {
target: "unlit",
},
},
},
},
description: "A light bulb machine",
id: "lightBulb",
});
She then used this lightBulb x-state machine in her component using the @xstate/vue library as follows:
At this point, you all must be saying. Wow! Dianne is brilliant. Yes, you're right. She's amazingly Brilliant. In fact, before this interview, she had enrolled in JSchool. That's why she could precisely make informed choices for the tool to use here.
JSchool is our mentorship program that aims at practically equipping future developers with intuitive skills for the ever-growing software development market. Learn more.