# Giggle With Deterministic Finite State

Recently, at our company, candidates were given a seemingly trivial but exciting challenge related to **state management**.

## **The Challenge**

*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.\*

### **Attempt 1: Use of conditional statements (booleans)**

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.

```javascript
  <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.

### Attempt 2: Enumerating the state

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:

```javascript
<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.

### **Attempt 3: Use of state machines (x-state)**

Without further adieu, let me tell you who won. Diane; knew precisely what the right tool for the job was. [X-State!](https://xstate.js.org/docs/guides/start.html#our-first-machine) First, she used [X-State's Visualizer](https://xstate.js.org/docs/visualizer/#write-and-visualize-your-code) to design a lightbulb state machine as shown below:

![Screen Shot 2022-10-28 at 10.51.36 PM.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1667019236235/Q5rJOuKLY.png align="left")

The tool automatically generated the javascript code below which represents the lightbulb finite state machine

```javascript
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](https://xstate.js.org/docs/packages/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.
