skip to Main Content

I want to create a form of sorts that displays questions that the user can navigate to access other answers/questions. Depending on the answer, it will display another question/answer.

Let’s say I have:

var json = 
     {
      "Did you restart the computer?": [
        {
          "Yes": [
            {
              "Is the software running?": [
                {
                  "Yes": "Cannot help",
                  "No": "Open it"
                }
              ]
            }
          ],
          "No": "Please restart it"
        }
      ]
    }

Is there a data structure that lets me access the option Yes/No by index? For example, doing json[0][0] or json[0][1].

Let’s say the user selects Yes on the first set of options. I know I can access the keys by doing

Object.keys(json["Did you restart the computer?"][0]["Yes"][0])
>> ['Is the software running?']

And if the user selects Yes again, I know I can access the keys by doing

Object.keys(json["Did you restart the computer?"][0]["Yes"][0]["Is the software connected to the server?"][0])
>> (2) ['Yes', 'No']

But this seems somehow cumbersome. Is there a better way to do this so I can access keys/values using indexes (ex. json[0][0][1])?

2

Answers


  1. I should preface this by saying, I don’t think it is a very good question for StackOverflow (it is a good question, but to answer it you may get very opinion based responses — which StackOverflow is often not about).

    You can access objects by keys, if you want to use indexes the simplest thing is to use an array, and also remove the text element from your data structure. It could be that you use a structure more like this:

    const options = [
      {
        type: "question",
        text: "Have you done this?",
        yes: {
          text: "Yes",
          options: [{
            type: "question",
             text: "Is the software running?",
             yes: {
               text: "Yes",
               options: [{
                 type: "message",
                 text: "Can't help",
               }]
             },
            no: {
              text: "No",
              options: [{
                type: "message",
                text: "Call for help",
              }]
            }
          }]
        },
        no: {
          type: "question",
          text: "No",
          options: [{
            type: "question",
            text: "have you tried this other thing?",
            options: [
              `...`
            ]
          }]
        }
      }
    ]
    

    Now options[0].yes.options[0].yes.options[0].text is Can't help.

    Login or Signup to reply.
  2. If you restructure the JSON to use arrays, you can simplify the tests

    document.addEventListener('DOMContentLoaded', () => {
      const questionElement = document.getElementById('question');
    
      let currentStep = paths[0]; // start
    
      const updateQuestion = () => {
        const isString = typeof currentStep === 'string';
        questionElement.innerHTML = isString ? currentStep : currentStep.question;
        yesBtn.hidden = isString;
        noBtn.hidden = isString;
      };
    
      document.getElementById('container').addEventListener('click', (e) => {
        const which = e.target.id === 'yesBtn' ? 0 : 1
        if (currentStep.answers && currentStep.answers[which]) {
          const next = currentStep.answers[which].next;    
          currentStep = Array.isArray(next) ? next[0] : next;
          updateQuestion();
        }
      });
      updateQuestion();
    });
    #container {
      text-align: center;
      margin-top: 50px;
    }
    
    #question {
      margin-bottom: 20px;
    }
    
    .btn {
      margin: 5px;
      padding: 10px 20px;
      cursor: pointer;
    }
    <div id="container">
      <div id="question"></div>
      <button class="btn" id="yesBtn" hidden>Yes</button>
      <button class="btn" id="noBtn" hidden>No</button>
    </div>
    
    <script>
      const paths = [{
        "question": "Did you restart the computer?",
        "answers": [{
            "response": "Yes",
            "next": [{
              "question": "Is the software running?",
              "answers": [{
                  "response": "Yes",
                  "next": "Cannot help"
                },
                {
                  "response": "No",
                  "next": "Open it"
                }
              ]
            }]
          },
          {
            "response": "No",
            "next": "Please restart it"
          }
        ]
      }];
    </script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search