Home > Enterprise >  How do I check the answer of a clicked button to see if it matches the correct answer found within a
How do I check the answer of a clicked button to see if it matches the correct answer found within a

Time:08-11

I have a trivia app that is almost complete. It contains an array of objects (being imported from a separate JavaScript file) containing all of my questions and four possible answers. I have a function that generates a random question from that array, stores the value into a global variable called randomQuestion and populates the HTML buttons with four possible answers.

I previously used the onClick event for each button within the HTML. That worked, however, there were too many questions to include in the primary JavaScript file. I moved them and exported/imported them to the app’s primary file. When I did this my checkAnswer function no longer worked, and I got the Uncaught TypeError warning. I was informed that in order to fix this I needed to remove the onClick events from the HTML file and addEventListeners to the buttons within the primary file.

Within the primary file I have captured each button with getElementById and have added click event listeners to each of the button variables. When the button is clicked the checkAnswer function should check if the selected answer is equal to the correct answer, and console.log “correct” or “incorrect”.

My problem is that I don't know how to capture the value of the answer button that is clicked and compare that to the correct answer value within the current randomQuestion. The code below is what I’m working with.

<button id="answers-btn-1" ></button>
<button id="answers-btn-2" ></button>
<button id="answers-btn-3" ></button>
<button id="answers-btn-4" ></button>
function checkAnswer() {
  answer = randomQuestion.answers;
  if(answer.correct === true) {
    console.log("Correct!");
  } else {
    console.log("Incorrect");
  }
}
export const questions = [
    {
        question: 'What year did the United States gain independence?',
        answers: [
          { text: '1776', correct: true },
          { text: '1676', correct: false },
          { text: '1576', correct: false },
          { text: `1476', correct: false }
        ]
      },

CodePudding user response:

Instead of creating the HTML up-front this example builds the HTML from the question/answer data, adds it to the DOM, and adds one listener to a buttons container which (using event delegation) captures events from its child elements (the buttons) as they "bubble up" the DOM.

To steer away from global variables checkAnswer accepts the array of answers and returns a new function (closure) when it is called.

answers.addEventListener('click', checkAnswer(question.answers));

That function is assigned to the listener and called when the listener is fired.

const questions=[{question:"What year did the United States gain independence?",answers:[{text:"1776",correct:true},{text:"1676",correct:false},{text:"1576",correct:false},{text:"1476",correct:false}]},{question:"What star does Earth orbit?",answers:[{text:"Moon",correct:false},{text:"Proxima Centauri",correct:false},{text:"Sun",correct:true},{text:"Roy Orbison",correct:false}]}];

// `checkAnswers` accepts the answers for the question
// and returns a new function (closure) that is assigned to the
// listener which fires when any of the child elements
// (the buttons) of the container `.answers` is clicked
// The closure keeps a reference to the answers when it is returned
function checkAnswer(answers) {
  return function(e) {

    // If the clicked child element is a button
    // get its textContent, `find` the correct answer
    // from the answers array, destructure its text value
    // and then compare it to the textContent of the clicked button
    if (e.target.matches('.answer')) {
      const { textContent } = e.target;
      const { text } = answers.find(answer => answer.correct);
      if (textContent === text) {
        console.log('Correct');
      } else {
        console.log('Incorrect');
      }
    }
  }
}

// Accepts the question answers and builds
// the buttons HTML
function buildAnswers(answers) {
  return answers.map(answer => {
    return `<button >${answer.text}</button>`;
  }).join('');
}

// Builds the question which is added to the
// element with the `question` class. It adds the
// question to an <h3> elementm, and calls `buildAnswers`
// with the answers as an argument to return the answers HTML
// Note: `map` returns an array so we need to join into into
// a string
function buildQuestion(question) {
  return `
    <h3>${question.question}</h3>
    <section >
      ${buildAnswers(question.answers)}
    </section>
  `;
}

// Get a random number based on the length of
// the questions array
function rnd(questions) {
  return Math.floor(Math.random() * questions.length);
}

// The main function
// 1) Gets a random question from the array
// 2) Gets the question element
// 3) Creates the question HTML
// 4) Inserts the HTML into the question element
// 5) It grabs the answers container element
// 6) Adds an event listener to it which calls `checkAnswer`
// with the set of available answers as an argument, which
// returns a function that is used when a button is clicked
function main() {
  
  const question = questions[rnd(questions)];
  const el = document.querySelector('.question');
  const html = buildQuestion(question);
  el.insertAdjacentHTML('beforeend', html);
  
  const answers = document.querySelector('.answers');
  answers.addEventListener('click', checkAnswer(question.answers));

}

// Call main
main();
.answer { margin-right: 0.3em; border-radius: 5px; }
.answer:hover { cursor: pointer; background-color: lightblue;}
<section ></section>

Additional documentation

CodePudding user response:

You can use form with submit buttons

const questions = [
    {
        question: 'What year did the United States gain independence?',
        answers: [
          { text: '1776', correct: true },
          { text: '1676', correct: false },
          { text: '1576', correct: false },
          { text: '1476', correct: false }
        ]
      }];
      
const currentQ = questions[0];

document.getElementById('question').textContent = currentQ.question;
const form = document.getElementById('form');
for (let i = 0; i < currentQ.answers.length; i  ) {
  const btn = document.createElement('button');
  btn.type = 'submit';
  btn.textContent = currentQ.answers[i].text;
  btn.value = currentQ.answers[i].text;
  form.appendChild(btn);
}

function handleSubmit(e) {
  e.preventDefault();
  const answer = e.submitter.value;
  const correctAnswer = currentQ.answers.find(ans => ans.correct);
  console.log(answer === correctAnswer.text ? 'Correct' : 'Incorrect');
  
}
<form id="form" onsubmit="handleSubmit(event)">
  <p id="question">question?</p>
</form>

  • Related