Quiz Troubleshooting: Understanding Why Your Quiz Isn't Progressing to the Next Question

I've been working on creating a quiz with branching logic - you can check out my progress in this Fiddle. I've looked into similar projects like those discussed here and here, but their solutions didn't quite fit what I needed for my quiz since I'm sticking to plain Javascript.

The structure of my quiz employs a tree-like system. For instance, the first question might be about wine preference, leading to further sub-questions based on the initial answer. The ultimate goal is to guide the user toward a specific result.

However, the issue that I'm facing is getting stuck before being able to present the second set of questions and choices.

I suspect that there might be an error within my questions array object variable.

Although I successfully linked my buttons to the initial labels (white and red) inside the beginQuiz function to access the top level of the tree, I encounter difficulties when attempting to delve deeper into the array - resulting in an undefined error message.

For instance (within the showQuestion function):

topBtn.innerHTML = questions[questionIndex].question.choices.label;
bottomBtn.innerHTML = questions[questionIndex].question.choices.label;

After selecting one of the choice buttons, the question area displays 'undefined'.

This is the error thrown: Uncaught TypeError: Cannot read properties of undefined (reading 'question')

While I can successfully fetch the first question and choices using the beginQuiz function, I seem unable to progress to the subsequent set. What could I be missing?

How can I advance to display and interact with the next batch of questions and labels?

Thank you in advance for any assistance provided.

const questions = [
  {
    question: {
      text: 'What type of wine do you like?',
      choices: [
        {
          label: 'white',
          path: 1,
          question: {
            text: 'I prefer...',
            choices: [
              {
                label: 'sparkling',
                path: 11,
              },
              {
                label: 'still',
                path: 12,
              },
            ],
          },
        },
        {
          label: 'red',
          path: 2,
          question: {
            text: 'I prefer...',
            choices: [
              {
                label: 'sparkling',
                path: 21,
              },
              {
                label: 'still',
                path: 22,
              },
            ],
          },
        },
      ],
    },
  },
];

topBtn.addEventListener('click', nextQuestion);
bottomBtn.addEventListener('click', nextQuestion);
restartBtn.addEventListener('click', restart);

let questionIndex = 0;

function beginQuiz() {
  let questionIndex = 0;
  questionText.innerHTML = questions[questionIndex].question.text;
  topBtn.innerHTML = questions[questionIndex].question.choices[0].label;
  topBtn.addEventListener('click', () => {
    if (questionIndex < 2) {
      nextQuestion();
    }
  });
  bottomBtn.innerHTML = questions[questionIndex].question.choices[1].label;
  bottomBtn.addEventListener('click', () => {
    if (questionIndex < 2) {
      nextQuestion();
    }
  });
}

beginQuiz();

function showQuestion() {
  questionText.innerHTML = questions[questionIndex];
  topBtn.innerHTML = questions[questionIndex].question.choices.label;
  bottomBtn.innerHTML = questions[questionIndex].question.choices.label;
}

function nextQuestion() {
  questionIndex++;
  showQuestion();
}

Answer №1

const restartBtn = document.getElementById('restart');
const topBtn = document.getElementById('top-btn');
const bottomBtn = document.getElementById('bottom-btn');
const questionText = document.querySelector('.question');
const choiceText = document.querySelector('.choices');
const resultText = document.querySelector('.result');

const quizData = [
  {
    question: { 
      text: 'What is your favorite type of wine?',
      choices: [
        {
          label: 'white',
          path: 1,
          question: {
            text: 'Preference...',
            choices: [
              {
                label: 'sparkling',
                path: 11,
              },
              {
                label: 'still',
                path: 12,
              },
            ],
          },
        },
        {
          label: 'red',
          path: 2,
          question: {
            text: 'Preference...',
            choices: [
              {
                label: 'sparkling',
                path: 21,
              },
              {
                label: 'still',
                path: 22,
              },
            ],
          },
        },
      ],
    }, // index 0
  },
    {
    question: { 
      text: 'Another question for you?',
      choices: [
        {
          label: 'my answer here',
          path: 1,
          question: {
            text: 'Preference...',
            choices: [
              {
                label: 'sparkling',
                path: 11,
              },
              {
                label: 'still',
                path: 12,
              },
            ],
          },
        },
        {
          label: 'another response',
          path: 2,
          question: {
            text: 'Preference...',
            choices: [
              {
                label: 'sparkling',
                path: 21,
              },
              {
                label: 'still',
                path: 22,
              },
            ],
          },
        },
      ],
    }, // index 1
  },
];

topBtn.addEventListener('click', nextQuestion);
bottomBtn.addEventListener('click', nextQuestion);
restartBtn.addEventListener('click', restart);

let questionIndex = 0;

function startQuiz() {
  let questionIndex = 0;
  console.log(questionIndex, "index");
  questionText.innerHTML = quizData[questionIndex].question.text;
  console.log(quizData[questionIndex], "test");
  topBtn.innerHTML = quizData[questionIndex].question.choices[0].label;
  topBtn.addEventListener('click', () => {
    if (questionIndex < 3) {
      nextQuestion();
    }
  });
  bottomBtn.innerHTML = quizData[questionIndex].question.choices[1].label;
  bottomBtn.addEventListener('click', () => {
    if (questionIndex < 3) {
      nextQuestion();
    }
  });
}

startQuiz();

function displayQuestion() {
  questionText.innerHTML = quizData[questionIndex].question.text;
 
  topBtn.innerHTML = quizData[questionIndex].question.choices[0].label;
  bottomBtn.innerHTML = quizData[questionIndex].question.choices[1].label;
   console.log(quizData[questionIndex].question.choices[0].label, " questionText.innerHTML");
}

function nextQuestion() {
  questionIndex++;
  displayQuestion();
}


function restart() {
  questionIndex = 0;
  currentQuestion = 0;
  document.getElementById('question').style.display = 'block';
  document.getElementById('choices').style.display = 'block';
  document.getElementById('result').style.display = 'none';
  topBtn.classList.remove('hide');
  bottomBtn.classList.remove('hide');
  startQuiz();
}

function findProperty(obj, prop) {
  let result = [];
  function recursivelyFindProp(o, keyToBeFound) {
    Object.keys(o).forEach(function (key) {
      if (typeof o[key] === 'object') {
        recursivelyFindProp(o[key], keyToBeFound);
      } else {
        if (key === keyToBeFound) result.push(o[key]);
      }
    });
  }
  recursivelyFindProp(obj, prop);
  return result;
}

console.log(findProperty(quizData, 'label'));
console.log(findProperty(quizData, 'text'));
console.log(findProperty(quizData, 'path'));
body {
    background-color: darkkhaki;
    font-family: serif;
}
h1 {
    color: white;
    text-align: center;
}

.container {
  background-color: darkgoldenrod;
  position: relative;
  display: grid;
  justify-content: center;
  align-items: center;
  text-align: center;
  color: #fafafa;
  padding: 20px;
  border: 2px solid #fff;
  border-radius: 20px;
}

.question {
    font-size: 2em;
    width: 90%;
    height: auto;
    margin: auto;
    border-radius: 6px;
    text-align: center;
}
.choices {
    font-family: Courier, serif;
    color: white;
    margin-top: 2em;
}
.choice {
    cursor: pointer;
    font-size: 2em;
    text-align: center;
}

.btn {
  background-color: transparent;
  color: #fff;
  font-size: 12px;
  text-transform: uppercase;
  border: 3px solid #fff;
  border-radius: 10px;
  padding: 10px 20px;
  margin: 10px;
  cursor: pointer;
  outline: none;
  transition: all 0.5s ease;
}

.btn:hover {
  background-color: #fff;
  color: darkgoldenrod;
}
<body>
    <header><h1>Wine chooser</h1></header>
    <!--Quiz Box -->
    <div class="container">
        <div class="question" id="question"></div>
        <div class="choices" id="choices"></div>
          <button class="btn" id="top-btn"></button>
          <button class="btn" id="bottom-btn"></button>
          <div class="result" id="result"></div>
        </div>
      <div class="controls">
        <button class="btn btn-restart" id="restart">Restart</button>
      </div>

    <script src="test3.js"></script>
  </body>

Answer №2

When I manually specify the index as [0] in my code:

questionText.innerHTML = questions[0].question.text;
topBtn.innerHTML = questions[0].question.choices[0].label;

I can retrieve the first question and its corresponding choices/answers.

However, if I try this with [1]:

questionText.innerHTML = questions[1].question.text;
topBtn.innerHTML = questions[1].question.choices[0].label;

I receive 'undefined' as the output!

This suggests that there may be an issue with how the data structures are set up and accessed. It seems that index 1 is currently empty.

Additionally, there appears to be a missing step in assigning index numbers for labels, specifically at line 121 in the jsfiddle script.

 questionText.innerHTML = questions[questionIndex].question.text;

 topBtn.innerHTML = 
 questions[questionIndex].question.choices[0].label;
 bottomBtn.innerHTML = 
 questions[questionIndex].question.choices[1].label;

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I am struggling to understand how to make use of ajax and php to reload data for pagination

$(function(){ $('.page').click(function() { var paging = $(this).attr("name"); var dataString = 'page='+paging; $.ajax({ type: "POST", url: "<?php echo $backtrack; ?>shop.php", data: dataString, ...

Commit the incorrect file name with the first letter capitalized

There seems to be an issue with the git not recognizing the correct filename casing. I have a file named User.js in my workspace, but when checking the git status, it displays user.js instead. Despite repeatedly changing and committing as User.js, the gi ...

Guide on preventing access to a website's JavaScript file or concealing specific data within it

Currently, my website is being hosted on GitHub pages and I am working on a simple web app that requires an API call. The API call consists of a web URL with specific parameters, including a personal API key issued by the service. It's important not t ...

Top Method for Initiating AJAX Request on WebForms Page

Looking for the best way to execute an AJAX call in a WebForms application? While ASP.NET AJAX components are an option, some may find them a bit heavy compared to the cleaner approach in MVC. Page Methods can be used, but they require static methods ...

Utilizing d3.csv to load CSV data into an nvd3 multiBar Chart demonstration (in JSON format)

I am attempting to recreate a nvd3.js multiBar Chart using my own .csv data. While I have come across similar questions in the past, none of them have provided a solution specific to my current issue. Some suggestions involve utilizing d3.entries, d3.nest, ...

Import an array in Python from a text file formatted in ASCII style

Inside the file named "array.txt", there is a 5x5 array of two-digit numbers presented as follows: +-------------------------+ ¦ 34 ¦ 21 ¦ 32 ¦ 41 ¦ 25 ¦ +----+----+----+----+-----¦ ¦ 14 ¦ 42 ¦ 43 ¦ 14 ¦ 31 ¦ +----+----+----+----+-----¦ ¦ ...

What is the best way to implement a Fibonacci sequence using a for...of loop?

**Can someone show me how to generate Fibonacci numbers using the for...of loop in JavaScript?** I've tested out the following code and it's giving me the desired output: function createFibonacci(number) { var i; var fib = []; // Initi ...

Angular UI Router allows for the resolution of data before a state

When working on my angular sample route, I attempted to achieve the following: (function(angular){ 'use strict'; angular .module('appRouter',['ui.router']) .controller('routerCtrl',function( ...

Developing a continuous running test loop

Currently, I have a code that runs fine, but I am looking to modify it to run in a loop that counts the number of elements with the class="socal" and tests each link. module.exports = { 'Unitel Fitness - click' : function (browser) { bro ...

Error: Jquery unrecognized - syntax issue

How can I properly add or remove the active class from an element based on a data-filter attribute in jQuery? When I attempt to do this, I receive the following error message:Uncaught Error: Syntax error, unrecognized expression: li[data-filter=.arroz-1] $ ...

The value of the comment box with the ID $(CommentBoxId) is not being captured

When a user enters data in the comment box and clicks the corresponding submit button, I am successfully passing id, CompanyId, WorkId, and CommentBoxId to the code behind to update the record. However, I am encountering an issue as I also want to pass the ...

The issue with AngularJS Routing is that it fails to refresh the menu items when the URL and views are being

My current project involves implementing token-based authentication using the MEAN stack. The goal of my application is to display different menu items based on whether a user is logged in or not. When there is no token present, the menu should show option ...

Having trouble retrieving data from an array within a JSON object

I've spent countless hours searching for a solution to this issue, but no matter what I attempt, I keep running into the same error message. The dreaded error I keep encountering is: Fatal error: Cannot use object of type stdClass as array My curren ...

Implementing a pre-defined value for ajax in ajax programming for beginners

I'm looking for guidance on setting up a hardcoded value for the OnSuccess parameter. The code I'm referencing is not my own, but I believe it may be related to Ajax. I'm a bit confused about it. Specifically, I need to focus on the OnSucce ...

how to assign a value to a field automatically in PHP

Is it possible to send values such as name, email, and contact number from one URL like to another URL at ? I would like these values to be automatically displayed on the form of the target URL (http://www.otherurl.com/test.php). I do not have access to ...

JavaScript controller with numerous dependencies in AngularJS

I have created a new controller: .controller('myCtrl', function($scope, $route, $routeParams, $location) Now I am trying to inject something called SharedState. I attempted: .controller('chatCtrl' ['SharedState', function($ ...

Spotfire: Changing a URL in an input field after it has been entered by the user

Currently, I am faced with a challenge related to importing a file in spotfire based on the path provided by the user. To accomplish this, I am utilizing a data function written in R script. In R, it is essential to note that all "\" characters are n ...

A step-by-step guide on extracting nested ASP.NET DataGrid values with JavaScript

Looking to retrieve data from a nested data grid on an aspx page using JavaScript. Check out the following code snippet: <tr> <td colspan="2" align="center"> <asp:DataGrid ID="sampleData" AutoGenerateColumns="false" runat="serv ...

Switching code from using .hover() to using .click() while still maintaining the functionality of both.orChanging code to switch

How can I change this script to trigger on click and also maintain the hover functionality: $x = jQuery.noConflict(); $x(document).ready(function () { $x(".swatch-anchor").on('click hover', function () { var newTitle = $x(this).attr( ...

Conceal certain values within an array

Scenario: Given an array: array([[1, 2, 0, 3, 4], [0, 4, 2, 1, 3], [4, 3, 2, 0, 1], [4, 2, 3, 0, 1], [1, 0, 2, 3, 4], [4, 3, 2, 0, 1]], dtype=int64) And a set of "bad" values: {2, 3} The objective is to generate a ma ...