0

I could use your help, my code works in codepen/jsfiddle even here, but not locally. I am trying to understand why it isnt working, but have not yet figured it out.

var myQuestions = [
 {
  question: "What is 10/2?",
  answers: {
   a: '3',
   b: '5',
   c: '115'
  },
  correctAnswer: 'b'
 },
 {
  question: "What is 30/3?",
  answers: {
   a: '3',
   b: '5',
   c: '10'
  },
  correctAnswer: 'c'
 }
];

var quizContainer = document.getElementById('quiz');
var resultsContainer = document.getElementById('results');
var submitButton = document.getElementById('submit');

generateQuiz(myQuestions, quizContainer, resultsContainer, submitButton);

function generateQuiz(questions, quizContainer, resultsContainer, submitButton){

 function showQuestions(questions, quizContainer){
  // we'll need a place to store the output and the answer choices
  var output = [];
  var answers;

  // for each question...
  for(var i=0; i<questions.length; i++){
   
   // first reset the list of answers
   answers = [];

   // for each available answer...
   for(letter in questions[i].answers){

    // ...add an html radio button
    answers.push(
     '<label>'
      + '<input type="radio" name="question'+i+'" value="'+letter+'">'
      + letter + ': '
      + questions[i].answers[letter]
     + '</label>'
    );
   }

   // add this question and its answers to the output
   output.push(
    '<div class="question">' + questions[i].question + '</div>'
    + '<div class="answers">' + answers.join('') + '</div>'
   );
  }

  // finally combine our output list into one string of html and put it on the page
  quizContainer.innerHTML = output.join('');
 }


 function showResults(questions, quizContainer, resultsContainer){
  
  // gather answer containers from our quiz
  var answerContainers = quizContainer.querySelectorAll('.answers');
  
  // keep track of user's answers
  var userAnswer = '';
  var numCorrect = 0;
  
  // for each question...
  for(var i=0; i<questions.length; i++){

   // find selected answer
   userAnswer = (answerContainers[i].querySelector('input[name=question'+i+']:checked')||{}).value;
   
   // if answer is correct
   if(userAnswer===questions[i].correctAnswer){
    // add to the number of correct answers
    numCorrect++;
    
    // color the answers green
    answerContainers[i].style.color = 'lightgreen';
   }
   // if answer is wrong or blank
   else{
    // color the answers red
    answerContainers[i].style.color = 'red';
   }
  }

  // show number of correct answers out of total
  resultsContainer.innerHTML = numCorrect + ' out of ' + questions.length;
 }

 // show questions right away
 showQuestions(questions, quizContainer);
 
 // on submit, show results
 submitButton.onclick = function(){
  showResults(questions, quizContainer, resultsContainer);
 }

}
body{
 font-size: 20px;
 font-family: sans-serif;
 color: #333;
}
.question{
 font-weight: 600;
}
.answers {
    margin-bottom: 20px;
}
#submit{
 font-family: sans-serif;
 font-size: 20px;
 background-color: #297;
 color: #fff;
 border: 0px;
 border-radius: 3px;
 padding: 20px;
 cursor: pointer;
 margin-bottom: 20px;
}
#submit:hover{
 background-color: #3a8;
}
<div id="quiz"></div>
<button id="submit">Get Results</button>
<div id="results"></div>

however when i do the same locally i get error of Cannot set property 'innerHTML' of null

heres a link too https://aaronlilly.github.io/Example/newexample/quiz.html please help :) i am not sure why it is not working locally. the error is on line 68.quizContainer.innerHTML = output.join('');

aaron lilly
  • 274
  • 1
  • 13

1 Answers1

1

Most likely you have put the javascript block inside the <head> section of your html document.

That means the browser comes to this line of your script

quizContainer = document.getElementById('quiz');

and tries to find the HTML element with the ID of quiz but it doesn't exist yet because it's defined inside the body thus it's undefined and you get the error message:

Cannot set property 'innerHTML' of null

To get around this move the javascript block to the end of the <body>.

obscure
  • 8,071
  • 2
  • 9
  • 30