TransWikia.com

Why are all the answers for my javascript quiz come back as wrong?

Stack Overflow Asked by Sean Urbassik on November 26, 2020

No matter which answer I select my answer always comes back as wrong. Im not sure where the issue is, I think its because I have an event listener on each button to check the answer.

Here is the code for how I get my elements

var questionLocation = document.getElementById("questionLocation")
var answerA = document.getElementById("answerA")
var answerB = document.getElementById("answerB")
var answerC = document.getElementById("answerC")
var answerD = document.getElementById("answerD")

window.addEventListener("load", function pullRandom() {
  let randomQ = myQuestions[Math.floor(Math.random() * myQuestions.length)];
  console.log(randomQ)

  questionLocation.innerHTML = randomQ.Question;
  answerA.innerHTML = randomQ.answers.a;
  answerB.innerHTML = randomQ.answers.b;
  answerC.innerHTML = randomQ.answers.c;
  answerD.innerHTML = randomQ.answers.d;
  var correct = randomQ.correctAnswer;
  console.log(correct)

These are my buttons

<div class="jumbotron" id="jumbotron">
  <div id="questionHolder" style="display: block;">
    <h4 id="questionLocation"></h4>
    <div id="answers">
      <div id="answerA" class="btn btn-dark"></div>
      <div id="answerB" class="btn btn-dark"></div>
      <div id="answerC" class="btn btn-dark"></div>
      <div id="answerD" class="btn btn-dark"></div>
    </div>
  </div>
</div>

Here are a sample of my question array

const myQuestions = [{
    Question: "What alloy is Captain America's sheild made of?",
    answers: {
      a: "Steel",
      b: "Adamantium",
      c: "Vibrainium",
      d: "Uru"
    },
    correctAnswer: "c"
  },
  {
    Question: "What was the code name of the Government project that gave Captain America his powers?",
    answers: {
      a: "Weapon X",
      b: "Super Soldier",
      c: "AIM",
      d: "Hyrda"
    },
    correctAnswer: "b"
  },
  {
    Question: "What was the name of the Virtual Intellegnce designed by Iron man?",
    answers: {
      a: "Jarvis",
      b: "Hal 9000",
      c: "T-800",
      d: "R2-D2"
    },
    correctAnswer: "a"
  },
  {
    Question: "What did Iron man build to power his suits and keep himself alive?",
    answers: {
      a: "Skynet",
      b: "Death Star",
      c: "Gamma Bomb",
      d: "Arc Reactor"
    },
    correctAnswer: "d"
  }
]

And these are the event listeners I have to check the answer

answerA.addEventListener("click", function checkAnswers(answer) {
  if (correct == answerA) {
    alert("Correct!")
    score++;
  } else {
    alert("Wrong!")
    console.log(score)
  }
});

answerB.addEventListener("click", function checkAnswers(answer) {
  if (correct == answerB) {
    alert("Correct!")
    score++;
  } else {
    alert("Wrong!")
    console.log(score)
  }
});

answerC.addEventListener("click", function checkAnswers(answer) {
  if (correct == answerC) {
    alert("Correct!")
    score++;
  } else {
    alert("Wrong!")
    console.log(score)
  }
});

answerD.addEventListener("click", function checkAnswers(answer) {
  if (correct == answerD) {
    alert("Correct!")
    score++;
  } else {
    alert("Wrong!")
    console.log(score)
  }
});

I’m not sure exactly where I’m going wrong.

3 Answers

I recommend the following:

  1. Know your choices a, b, c, d, etc...
  2. Add data attributes to each HTML choice for quick look-up
  3. Add the event listeners to each of the elements; up-front
  4. Retrieve a random question
  5. Populate the textContent of each "button"
  6. Check the answer by comparing data attribute to the correct choice

This introduces looping to dynamically set-up the content of the question form.

Checking the answer is now as simple as:

e.target.dataset.choice === randomQ.correctAnswer

const myQuestions = getQuestions();
const choices = ['a', 'b', 'c', 'd'];

let score = 0;
let randomQ = null;

const main = () => {
  choices.forEach(x => {
    document.getElementById('answer' + x.toUpperCase())
      .addEventListener('click', checkAnswers)
  });

  prepareQuestion();
};

const prepareQuestion = () => {
  randomQ = retrieveRandomQuestion(myQuestions);
  const questionLocation = document.getElementById("questionLocation");
  questionLocation.innerHTML = randomQ.Question;
  choices.forEach(x => {
    var choice = document.getElementById('answer' + x.toUpperCase());
    choice.textContent = randomQ.answers[x];
  });
}

const checkAnswers = (e) => {
  if (e.target.dataset.choice === randomQ.correctAnswer) {
    alert("Correct!");
    score++;
    prepareQuestion(); // Ask another random question
  } else {
    alert("Wrong!");
    console.log(`Final score: ${score}`);
  }
}

const retrieveRandomQuestion = (questions) =>
  questions[Math.floor(Math.random() * questions.length)];

main();

// Convenience function to retrieve data above...

function getQuestions() {
  return [{
    Question: "What alloy is Captain America's sheild made of?",
    answers: {
      a: "Steel",
      b: "Adamantium",
      c: "Vibrainium",
      d: "Uru"
    },
    correctAnswer: "c"
  }, {
    Question: "What was the code name of the Government project that gave Captain America his powers?",
    answers: {
      a: "Weapon X",
      b: "Super Soldier",
      c: "AIM",
      d: "Hyrda"
    },
    correctAnswer: "b"
  }, {
    Question: "What was the name of the Virtual Intellegnce designed by Iron man?",
    answers: {
      a: "Jarvis",
      b: "Hal 9000",
      c: "T-800",
      d: "R2-D2"
    },
    correctAnswer: "a"
  }, {
    Question: "What did Iron man build to power his suits and keep himself alive?",
    answers: {
      a: "Skynet",
      b: "Death Star",
      c: "Gamma Bomb",
      d: "Arc Reactor"
    },
    correctAnswer: "d"
  }];
}
body {
  background: #112;
}

#questionHolder {
  color: #FFF;
  text-align: center;
}

#answers {
  display: flex;
  flex-wrap: wrap;
}

.btn {
  flex: calc(50% - 2em);
  width: 8em;
  margin: 0.25em 0;
  padding: 0.5em;
  margin: 0.25em;
  text-align: center;
  border: thin solid #557;
}

.btn:hover {
  cursor: pointer;
  font-weight: bold;
}

.btn-dark {
  background: #225;
  color: #FFF;
}

.btn-dark:hover {
  background: #ED0;
  color: #000;
}

.btn-dark:active {
  background: #F70;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.1/css/bootstrap.min.css">
<div class="jumbotron" id="jumbotron">
  <div id="questionHolder" style="display: block;">
    <h4 id="questionLocation"></h4>
    <div id="answers">
      <div id="answerA" class="btn btn-dark" data-choice="a"></div>
      <div id="answerB" class="btn btn-dark" data-choice="b"></div>
      <div id="answerC" class="btn btn-dark" data-choice="c"></div>
      <div id="answerD" class="btn btn-dark" data-choice="d"></div>
    </div>
  </div>
</div>

Answered by Mr. Polywhirl on November 26, 2020

When you do if( correct == answerA ), you are comparing an HTML element

var answerA = document.getElementById("answerA")

with a string

var correct = randomQ.correctAnswer;

This is not a valid comparison, but there are multiple ways to achieve your goal: use the element's textContent to compare strings var answerA = document.getElementById("answerA").textContent, use the element's id var answer = answer.target.id.split("answer")[1] or use data-attributes like @T.J. Crowder suggested in his answer. (and probably more..)

Answered by nip on November 26, 2020

if( correct == answerA ){ compares a string (correct) with the HTML element for the answer (`answerA), not its text.

If you want to keep using answerA (answerB, etc.) for this comparison, then:

Given that you're setting the answer using innerHTML, you could use innerHTML for the comparison:

if( correct == answerA.innerHTML){

but, the HTML you get back from a browser may vary from the HTML you specify for it. If you want to get back exactly the text you put on it, you could store it in an attribute. Also, unless you really want to put HTML in the answers, use textContent rather than innerHTML:

answerA.textContent = randomQ.answers.a;
answerA.setAttribute("data-answer", randomQ.answers.a);

Then later

if( correct == answerA.getAttribute("data-answer")){

That said, I don't think I'd compare with the HTML element at all. I'd compare with the question's answers instead:

if( correct == randomQ.answers.a){

Answered by T.J. Crowder on November 26, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP