skip to Main Content

I am making a quiz webpage. Whenever option of last question is clicked I get error in the console. It says "cannot read properties of undefined". Because it exceeds the length of the quesAns object.
see my code

const question = document.querySelector(".ques");
const first = document.querySelector(".first");
const second = document.querySelector(".second");
const third = document.querySelector(".third");
const fourth = document.querySelector(".fourth");
const answers = document.querySelectorAll(".ans");
const rightAnswer = document.querySelector(".right_ans");

let seq = 0;
let seq2 = -1;

const quesAns = [
  {
    ques: "Who is the CEO of Google?",
    a: "A. Bill Gates",
    b: "B. Tim Cook",
    c: "C. Sundar Pichai",
    d: "D. Larry Page",
    true: "C. Sundar Pichai",
  },
  {
    ques: "Who is founder of Microsoft",
    a: "A. Elon Musk",
    b: "B. Steve Jobs",
    c: "C. Mark Jukerberg",
    d: "D. Bill Gates",
    true: "D. Bill Gates",
  },
  {
    ques: "Who is founder of Facebook?",
    a: "A. Mark Zukerberg",
    b: "B. Larry Page",
    c: "C. Satya Nadela",
    d: "D. Evan Spiegel",
    true: "A. Mark Zukerberg",
  },
  {
    ques: "Who is richest person in the world?",
    a: "A. Mark Zukerberg",
    b: "B. Elon Musk",
    c: "C. Bill gates",
    d: "D. Mukesh Ambani",
    true: "B. Elon Musk",
  },
  {
    ques: "What is responsible for styling in web page?",
    a: "HTML",
    b: "XML",
    c: "CSS",
    d: "JavaScript",
    true: "CSS",
  }
];

function moreQA() {
  question.innerHTML = quesAns[seq].ques;
  first.innerHTML = quesAns[seq].a;
  second.innerHTML = quesAns[seq].b;
  third.innerHTML = quesAns[seq].c;
  fourth.innerHTML = quesAns[seq].d;
}

answers.forEach((ans) => {
  ans.addEventListener("click", (e) => {
    seq++;
    seq2++;
    if (quesAns[seq2].true == e.target.innerHTML.trim()) {
      rightAnswer.innerHTML = "Your answer is right";
      rightAnswer.style.color = "green";
    } else {
      rightAnswer.innerHTML = "Your answer is wrong";
      rightAnswer.style.color = "red";
    }
    moreQA();
  });
});

And I don’t want to repeat the question again from starting. Please tell me how can I avoid that error.

2

Answers


  1. you’re trying to load more questions that’s why you’re getting this error. you should check if there are more questions available before loading it

    function moreQA() 
      {
      if(quesAns.length >= seq) return;
    
      question.innerHTML = quesAns[seq].ques;
      first   .innerHTML = quesAns[seq].a;
      second  .innerHTML = quesAns[seq].b;
      third   .innerHTML = quesAns[seq].c;
      fourth  .innerHTML = quesAns[seq].d;
      }
    
    Login or Signup to reply.
  2. Here is a version that is easier to add questions to

    It just needs the object and it will create the questions. The next button will be disabled at the end of the questions so you will not have the problem of exceeding the length of the array

    It uses delegation to see which button was clicked and uses the label to show correct or not

    let cnt = 0;
    const questions = document.getElementById("questions");
    const result = document.getElementById("result");
    const next = document.getElementById("next");
    const ask = () => {
      result.innerHTML = ``;
      next.disabled = cnt>=quesAns.length-1;
    
      if (cnt >= quesAns.length) {
        return;
      }  
      const curr = quesAns[cnt];
      const correct = curr.correct;
      questions.innerHTML = `<h3>${curr.ques}</h3>`;
      //  console.log( Object.entries(curr))
      questions.innerHTML += Object.entries(curr).map(([key, value]) => ['ques', 'correct'].includes(key) ? '' : `<label data-val="${key}" data-correct="${correct === key}"><input type="radio" name="answer" />${key.toUpperCase()}: ${value}</label>`).join('<br/>');
      cnt++;
    };
    questions.addEventListener("click", (e) => {
      const tgt = e.target.closest("label");
      if (!tgt) return; // not an input
      const correct = tgt.dataset.correct === "true";
      questions.querySelectorAll("label").forEach(label => { // reset
        label.classList.toggle("correct", false);
        label.classList.toggle("incorrect", false);
      })
      tgt.classList.toggle("correct", correct);
      tgt.classList.toggle("incorrect", !correct);
      result.innerHTML = `Your answer is ${correct ? "correct" : "incorrect"}`;
    });
    next.addEventListener("click", ask);
    ask();
    .incorrect {
      color: red
    }
    
    .correct {
      color: green
    }
    <div id="questions"></div>
    <span id="result"></span>
    <hr/>
    <button type="button" id="next">Next</button>
    
    <script>
      const quesAns = [{
          ques: "Who is the CEO of Google?",
          a: "Bill Gates",
          b: "Tim Cook",
          c: "Sundar Pichai",
          d: "Larry Page",
          correct: "c"
        },
        {
          ques: "Who is founder of Microsoft",
          a: "Elon Musk",
          b: "Steve Jobs",
          c: "Mark Jukerberg",
          d: "Bill Gates",
          correct: "d"
        },
        {
          ques: "Who is founder of Facebook?",
          a: "Mark Zukerberg",
          b: "Larry Page",
          c: "Satya Nadela",
          d: "Evan Spiegel",
          correct: "a"
        },
        {
          ques: "Who is richest person in the world?",
          a: "Mark Zukerberg",
          b: "Elon Musk",
          c: "Bill gates",
          d: "Mukesh Ambani",
          correct: "b"
        },
        {
          ques: "What is responsible for styling in web page?",
          a: "HTML",
          b: "XML",
          c: "CSS",
          d: "JavaScript",
          correct: "c"
        }
      ];
    </script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search