How do I get the index of two variables, compare them, and return true or false

Viewed 71

I am making a trivia game that uses an array of objects.

const questions = [
    {
        question: 'What year did the United State become independent?',
        answers: [
          { text: '1776', correct: true },
          { text: '1676', correct: false },
          { text: '1576', correct: false },
          { text: '1876', correct: false }
        ]
      },

I think the correct way is to get the index of the correct answer by using .find, getting the the index of the selected answer, then use an if statement to compare the two. If they match then the console will log "correct" or "incorrect" otherwise. I am having trouble getting the index of corretAnswer and also selectedAnswer.

When I use this code and console log it, both variables return undefined.

const answerButtons = document.querySelectorAll('.answers-btn');

function checkAnswer() {

  let correctAnswer = randomQuestion.answers.find((answer, index) => {
    return answer[index] === true;
  })

  answerButtons.forEach((answerButton, index) => {
    answerButton.addEventListener('click', () => {
      let selectedAnswer = answerButton[index];
      return selectedAnswer;
    })
  })
}
<button id="answers-btn-1" onclick="checkAnswer()" class="answers-btn"></button>
<button id="answers-btn-2" onclick="checkAnswer()" class="answers-btn"></button>
<button id="answers-btn-3" onclick="checkAnswer()" class="answers-btn"></button>
<button id="answers-btn-4" onclick="checkAnswer()" class="answers-btn"></button>
5 Answers

I tried to create a solution with as least code possible. First, you don't need to add an event listener to each button, you could just make each call a specific index from HTML. Secondly, since you are creating your answers list with a correct property, you don't need to iterate it. Just get the one the user selected and check the property.

Hope it helps.

const currentQuestion = 0;

const questions = [{
  question: 'What year did the United State become independent?',
  answers: [{
      text: '1776',
      correct: true
    },
    {
      text: '1676',
      correct: false
    },
    {
      text: '1576',
      correct: false
    },
    {
      text: '1876',
      correct: false
    }
  ]
}]

function checkAnswer(bntIndex) {
  let answer = questions[currentQuestion].answers[bntIndex];
  console.log(answer.correct)
}
<button id="answers-btn-1" onclick="checkAnswer(0)" class="answers-btn">1</button>
<button id="answers-btn-2" onclick="checkAnswer(1)" class="answers-btn">2</button>
<button id="answers-btn-3" onclick="checkAnswer(2)" class="answers-btn">3</button>
<button id="answers-btn-4" onclick="checkAnswer(3)" class="answers-btn">4</button>

when you call .find((answer, index), answer will be an object, e.g. { text: '1776', correct: true }, so when you do return answer[index] === true it is checking if, e.g., { text: '1776', correct: true }[1] === true, but since { text: '1776', correct: true } doesn't have a property 1 that will always return false, so .find will return undefined.

To get the correct answer, you would instead just do

let correctAnswer = randomQuestion.answers.find((answer) => answer.correct);

Same idea for your forEach, answerButton is already the answer, so when you do let selectedAnswer = answerButton[index]; it will return undefined.

try

const questions = [
    {
        question: 'What year did the United State become independent?',
        answers: [
            { text: '1776', correct: true },
            { text: '1676', correct: false },
            { text: '1576', correct: false },
            { text: '1876', correct: false },
        ],
    },
];

const correctAnswerIndex = questions[0].answers.findIndex((answer) => (answer.correct === true))
const correctAnswer = questions[0].answers[correctAnswerIndex];
console.log('correctAnswer', correctAnswer);

const guess = '1776';

const userAnswerIndex = questions[0].answers.findIndex((answer) => (answer.text === guess))
const userAnswer = questions[0].answers[userAnswerIndex];
console.log('userAnswer', userAnswer);

if (correctAnswer.text === userAnswer.text) {
    console.log('You win');
}

Array.prototype.findIndex() returns the index position of the first matching item, as opposed to Array.prototype.find() which returns the first matching item.

findIndex parameter is a function that returns true or false. If it evaluates to true, it returns the index position of the matching element.

There's other ways you could do it too, like for example:

const guess = '1776';

const answer = questions[0].answers.find((answer) => (answer.text === guess))

if (answer.correct === true) {
    console.log('You win');
}

const questions = [
    {
      question: 'What year did the United State become independent?',
      answers: [
        { text: '1776', correct: true },
        { text: '1676', correct: false },
        { text: '1576', correct: false },
        { text: '1876', correct: false }
      ]
    }
];

const checkAnswer = function(index) {
  const answer = questions[0].answers[index];
  const correctAnswer = questions[0].answers.find((a) => a.correct === true);
  if (answer.text === correctAnswer.text) {
    alert('guessed correct');
  } else {
    alert('guess again');
  }
};

const answersButtons = document.querySelectorAll('.answers-btn');

for (let i = 0; i < answersButtons.length; i++) {
  answersButtons[i].innerText = questions[0].answers[i].text;
  answersButtons[i].onclick = function() {
    checkAnswer(i);
  };
}
<button id="answers-btn-1" class="answers-btn"></button>
<button id="answers-btn-2" class="answers-btn"></button>
<button id="answers-btn-3" class="answers-btn"></button>
<button id="answers-btn-4" class="answers-btn"></button>

This is based on Pelicer's answer, but with perhaps some more concepts that you might use:

  • Delegation
  • Leveraging built in features like the value of input elements.
  • Separation of code and presentation layers
  • Removal of unused elements/attributes

The method getQuestion is hardcoded as the selection method is out of scope for the question.

const questions =
[ { question: 'What year did the United State become independent?'
  , answers: [ { text: '1576' }
             , { text: '1676' }
             , { text: '1776', correct: true }
             , { text: '1876' }
             ]
  }
]

const getQuestion = (event) => questions[0]

function checkAnswer(event) {
  if (event.target.classList.contains('answers-btn')) {
    const question = getQuestion(event)
    const correct = question.answers.findIndex( answer => answer.correct )
    const selected = parseInt(event.target.value)
    console.log(`For the question "${question.question}", the answer "${question.answers[selected].text}" is ${ (selected == correct)?"correct":"incorrect" }`)
  }
}

document.addEventListener('click', checkAnswer)
<button value="0" class="answers-btn">A</button>
<button value="1" class="answers-btn">B</button>
<button value="2" class="answers-btn">C</button>
<button value="3" class="answers-btn">D</button>

const questions =
[ { question: 'What year did the United State become independent?'
  , answers: [ { text: '1576' }
             , { text: '1676' }
             , { text: '1776', correct: true }
             , { text: '1876' }
             ]
  }
]

const getQuestion = (event) => {
  return questions[parseInt(event.target.parentElement.getAttribute('data-question'))]
}

function checkAnswer(event) {
  if (event.target.classList.contains('answers-btn')) {
    const question = getQuestion(event)
    const correct = question.answers.findIndex( answer => answer.correct )
    const selected = parseInt(event.target.value)
    console.log(`For the question "${question.question}", the answer "${question.answers[selected].text}" is ${ (selected == correct)?"correct":"incorrect" }`)
  }
}

document.addEventListener('click', checkAnswer)

document.addEventListener('DOMContentLoaded', function() {
  const qDiv = document.getElementById('questions')
  let qHtml = ''
  for (qi = 0; qi < questions.length; qi++) {
    qHtml += `<div data-question="${qi}">${questions[qi].question}<br />`
    for (ai = 0; ai < questions[qi].answers.length; ai++)
      qHtml += `<button value="${ai}" class="answers-btn">${questions[qi].answers[ai].text}</button>`
  }
  qHtml += '</div>'
  qDiv.innerHTML = qHtml
})
<div id="questions">
</div>

Related