Spotlight on decision-tree
Tags: javascript, quiz, tree
Published: 2020-01-30 20:26:07

---
title: Spotlight on decision-tree
published: true
date: 2019-10-25 19:22:49 UTC
tags: javascript, quiz, tree
canonical_url: https://ianwalter.dev/spotlight-on-decision-tree/
---

![Spotlight on decision-tree](https://ianwalter.dev/content/images/2019/10/decision-tree-7.jpg)

I created [decision-tree](https://github.com/ianwalter/decision-tree) because I was creating a sort of online quiz and I wanted an abstraction to keep track of state as the user completed questions. With decision-tree, you can create a tree-like structure in which answers to questions determine which question or result is shown next as the user continues through the quiz. As the path (or branch) is constructed, it is stored so that the application can know how the user arrived at a result or allow them to backtrack if necessary.

Let’s take a look at an example. First, we need to construct the tree which consists of objects representing questions, options, and results. I apologize in advance for how geeky this example is:

```
const decisionTree = new DecisionTree({
  key: 'attribute',
  title: 'What is your greatest attribute?',
  options: [
    {
      key: 'S',
      label: 'Strength',
      leadsTo: 'proficiency'
    },
    {
      key: 'I',
      label: 'Intelligence',
      leadsTo: 'spells'
    },
    {
      key: 'D',
      label: 'Dexterity',
      leadsTo: 'proficiency'
    },
    {
      key: 'C',
      label: 'Charisma',
      leadsTo: 'bard'
    }
  ],
  children: [
    {
      key: 'spells',
      title: 'What are your preffered type of spells?',
      options: [
        {
          key: 'damage',
          label: 'Damage',
          leadsTo: 'mage'
        },
        {
          key: 'healing',
          label: 'Healing',
          leadsTo: 'cleric'
        }
      ],
      children: [
        {
          key: 'mage',
          title: 'Mage',
          description: `
            You are a powerful mage, hurling fireballs at your foes!
          `
        },
        {
          key: 'cleric',
          title: 'Cleric',
          description: `
            You are a knowledgeable cleric, saving your friends by casting
            spells to heal them.
          `
        }
      ]
    },
    {
      key: 'proficiency',
      title: 'What type of weapon are you most proficient with?',
      options: [
        {
          key: 'swords',
          label: 'Swords',
          leadsTo: dt => {
            if (dt.state.attribute === 'D') {
              return 'thief'
            } else {
              return 'fighter'
            }
          }
        },
        {
          key: 'bows',
          label: 'Bows',
          leadsTo: 'ranger'
        }
      ],
      children: [
        {
          key: 'fighter',
          title: 'Fighter',
          description: `
            You are a strong fighter, using your sword to cut down those who
            stand in your way!
          `
        },
        {
          key: 'thief',
          title: 'Thief',
          description: `
            You are a dexterous thief, piercing enemies before they even
            know what hit them.
          `
        },
        {
          key: 'ranger',
          title: 'Ranger',
          description: `
            You are a skilled ranger, felling combatants with your arrows.
          `
        }
      ]
    },
    {
      key: 'bard',
      title: 'Bard',
      description: `
        You are a talented bard, inspiring your party with heroic ballads.
      `
    }
  ]
})
```
<figcaption>Our decision-tree instance</figcaption>

Once a decision-tree instance is created, we can navigate it by setting answers to questions and calling `next` like:

```
decisionTree.set('attribute', 'D').next()
const result = decisionTree.set('proficiency', 'swords').next()
```
<figcaption>Initial tree navigation</figcaption>

In this example, if the node returned by `next` has no `leadsTo` property we can assume that we've reached a result. In the navigation above, we would have arrived at the result:

```
{
  key: 'thief',
  title: 'Thief',
  description: `
    You are a dexterous thief, piercing enemies before they even
    know what hit them.
  `
}
```
<figcaption>Initial result</figcaption>

If we wanted to arrive at a different result, we can call `prev` to go back to the previous question and change our answer like:

```
decisionTree.prev()
const result = decisionTree.set('proficiency', 'bows').next()
```
<figcaption>Changing our response to the previous question</figcaption>

Now our result would be:

```
{
  key: 'ranger',
  title: 'Ranger',
  description: `
    You are a skilled ranger, felling combatants with your arrows.
  `
}
```
<figcaption>New result</figcaption>

You can see decision-tree in action at the binx health website where it’s being used to power Find My Test, an assessment that helps people determine what kind of sexually-transmitted infection (STI) testing is suited for them: [https://app.mybinxhealth.com/find-my-test](https://app.mybinxhealth.com/find-my-test)

I hope this article was helpful in explaining how you would use decision-tree. If you find this utility useful, please [star it on GitHub](https://github.com/ianwalter/decision-tree) and consider [sponsoring me](https://github.com/sponsors/ianwalter)!

[

ianwalter/decision-tree

A utility for traversing decision trees by selecting options - ianwalter/decision-tree

 ![Spotlight on decision-tree](https://github.githubassets.com/favicon.ico)ianwalterGitHub

 ![Spotlight on decision-tree](https://repository-images.githubusercontent.com/156609988/5fdc1980-f738-11e9-89b0-e27bc5974b7c)
](https://github.com/ianwalter/decision-tree)