Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Tom Checkley
Tom Checkley
25,165 Points

Stuck....

I've followed along with this course and been through the project files. I'm trying to do the same course but instaed of using written questions i want to use images. Heres my code

// =====================
// QUIZ PROTOTYPE
// =====================
function Quiz(questions) {
    this.score = 0;
    this.questions = questions;
    this.currentQuestionIndex = 0;
}

Quiz.prototype.guess = function(answer) {
    if(this.getCurrentQuestion().isCorrectAnswer(answer)) {
        this.score++;
    }
    this.currentQuestionIndex++;
};

Quiz.prototype.getCurrentQuestion = function() {
    return this.questions[this.currentQuestionIndex];
};

Quiz.prototype.hasEnded = function() {
    return this.currentQuestionIndex >= this.questions.length;
}

// =====================
// QUESTION PROTOTYPE
// =====================
function Question(image, choices, answer) {
    this.image = image;
    this.choices = choices;
    this.answer = answer;
}

Question.prototype.isCorrectAnswer = function(choice) {
    return this.answer === choice;
}

// =====================
// QUIZ UI
// =====================
var QuizUI = {
    displayNext: function () {
    if (quiz.hasEnded()) {
        this.displayScore();
    } else {
        this.displayQuestion();
        this.displayChoices();
        this.displayProgress();
    }
  },
  displayQuestion: function() {
      this.populateIdWithHTML('pic-holder', quiz.getCurrentQuestion().image);
  },
  displayChoices: function() {
      var choices = quiz.getCurrentQuestion().choices;

      for(var i = 0; i < choices.length; i++) {
          this.populateIdWithHTML('choice'+i, choices[i]);
          this.guessHandler('guess'+i, choices[i]);
      }
  },
  displayScore: function() {
      var gameOverHTML = '<h1>Game Over</h1>';
      gameOverHTML += '<h2> Your score is: ' + quiz.score + '</h2>';
      this.populateIdWithHTML('quiz', gameOverHTML);
  },

  populateIdWithHTML: function(id, content) {
      var element = document.getElementById(id);
/////////////////////////////////////////////////////////////////////////

// THIS IS THE LINE THE ERROR IS ORIGINATING FROM
      element.innerHTML = content;

////////////////////////////////////////////////////////////////////////
  },
  guessHandler: function(id, guess) {
      var button = document.getElementById(id);
      button.onclick = function() {
          quiz.guess(guess);
          QuizUI.displayNext();
      }
  },

    displayProgress: function() {
        var currentQuestionNumber = quiz.currentQuestionIndex + 1;
        this.populateIdWithHTML('progress', 'Question ' + currentQuestionNumber + ' of ' + quiz.questions.length + '.');
    }
};

// =====================
// QUESTIONS
// =====================
var questions = [
    new Question('<img src="img/jp.jpg" alt="image of Jeff Goldblum">', ['Jurassic Park', 'Independence Day', 'The Life Aquatic'], 'Jurassic Park'),

    new Question('<img src="img/annie.jpg" alt="image of Jeff Goldblum">', ['Cats and Dogs', 'Annie Hall', 'The Grand Budapest Hotel'], 'Annie Hall'),

//and so on

the html

<div id="quiz" class="panel">
  <p>Which film is this picture of Jeff taken from?</p>
    <div id="pic-holder"></div>
    <div class="btn-holder">
        <p id="choice0"></p>
        <button id="guess0">Select Answer</button>

        <p id="choice1"></p>
        <button id="guess1">Select Answer</button>

        <p id="choice2"></p>
        <button id="guess2">Select Answer</button>
    </div>
</div>

I'm getting an error message saying 'cannot set poperty innerHTML of null' it is happening on the line I've put a massive comment block around. If anyone can point out what i'm doing wrong/missing I'd be realy greatful. Thanks

1 Answer

Ryan Ruscett
Ryan Ruscett
23,309 Points

Try something like this. You have an innerHTML element on the document object. So get the document object, and get the element which should have an ID associated with it on the HTML page. Then you can get the innerHTML and set it to something if you want.

Not sure if this helps but let me know.

document.getElementById("something").innerHTML = "something";
Tom Checkley
Tom Checkley
25,165 Points

Thanks Ryan, I see what you mean. Though the function is supposed to work on multiple elements so can't really stay dry in this manner. I really don't get why it's not working. The arguments are being passed to it. For example

displayQuestion: function() {
      this.populateIdWithHTML('pic-holder', quiz.getCurrentQuestion().image);
  },

so, as i understand it, this should pass the the populateIdWithHTML function the string 'pic-holder' as the id and then find the image attached to the current question. I've tried updating my code to use an if statement as i thought that the image probably needed to be appended instead of innerHTML that looks like this, though it's still not working

populateIdWithHTML: function(id, content) {
      var element = document.getElementById(id);
      if(id == 'pic-holder') {
        document.getElementById('pic-holder').appendChild(content);
      } else {
        element.innerHTML = content;
      }   
  },