How to fix "Cannot read property 'addEventListener' of null" error

36,804

You are loading the Javascript file in the <head>, before the body of your HTML Is loaded. Therefore your line

const guessSubmit = document.querySelector('.guessSubmit');

Has nothing to look up - your button with class guessSubmit doesn't exist yet. And since guessSubmit is null, it does not contain any properties, hence the error.

The easiest solution is to put your <script> tag at the bottom of your HTML body rather than the head. This way it will load your Javascript after the DOM is completely loaded.

Alternative ways include adding event listeners to run your script after the DOM is loaded, such as DOMContentLoaded. See more here: https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded.

Share:
36,804
Gourav Thakur
Author by

Gourav Thakur

Updated on January 14, 2020

Comments

  • Gourav Thakur
    Gourav Thakur over 4 years

    I am learning javascript from Mozilla developer network(MDN). I am getting error in Number guessing game. The error says "Uncaught TypeError: Cannot read property 'addEventListener' of null" at line 46.

    Screenshot of Error

    I have checked and matched code line by line many times but i am unable to resolve the problem. The code works partially(some functions don't work) when I remove script.js external file and put the code in index.html inside tag. Here's the code. Please understand that the javascript code and HTML are in different file.

    let randomNumber = Math.floor(Math.random() * 100) + 1;
    
    const guesses = document.querySelector('.guesses');
    const lastResult = document.querySelector('.lastResult');
    const loworHi = document.querySelector('.loworHi');
    
    const guessSubmit = document.querySelector('.guessSubmit');
    const guessField = document.querySelector('.guessField');
    
    let guessCount = 1;
    let resetButton;
    
    
    function checkGuess() {
      let userGuess = Number(guessField.value);
      if (guessCount === 1) {
        guesses.textContent = 'Previous guesses: ';
      }
    
      guesses.textContent += userGuess + ' ';
    
      if (userGuess === randomNumber) {
        lastResult.textContent = 'Congratulations! You got it right!';
        lastResult.style.backgroundColor = 'green';
        loworHi.textContent = '';
        setGameOver();
      } else if (guessCount === 10) {
        lastResult.textContent = '!!!GAME OVER!!!';
        setGameOver();
      } else {
        lastResult.textContent = 'Wrong!';
        lastResult.style.backgroundColor = 'red';
        if (userGuess < randomNumber) {
          loworHi.textContent = 'Last guess was too low!';
        } else if (userGuess > randomNumber) {
          loworHi.textContent = 'Last guess was too high!';
        }
      }
      guessCount++;
      guessField.value = '';
      guessField.focus();
    
    }
    
    guessSubmit.addEventListener('click', checkGuess);
    
    function setGameOver() {
      guessField.disabled = true;
      guessSubmit.disabled = true;
      resetButton = document.createElement('button');
      resetButton.textContent = 'Start new game';
      document.body.appendChild(resetButton);
      resetButton.addEventListener('click', resetGame);
    }
    
    function resetGame() {
      guessCount = 1;
    
      const resetParas = document.querySelectorAll('.resultParas p');
      for (let i = 0; i < resetParas.length; i++) {
        resetParas[i].textContent = '';
      }
    
      resetButton.parentNode.removeChild(resetButton);
    
      guessField.disabled = false;
      guessSubmit.disabled = false;
      guessField.value = '';
      guessField.focus();
    
      lastResult.style.backgroundColor = 'white';
    
      randomNumber = Math.floor(Math.random() * 100) + 1;
    } 
    
    
    
    
    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <link rel="stylesheet" type="text/css" href="style.css">
        <script type="text/javascript" src="script.js"></script>
        <title>Number guessing game</title>
    
    </head>
    
    <body>
        <h1>Number guessing game</h1>
    
        <p>We have selected a random number between 1 and 100. See if you can guess it in 10 turns or fewer. 
            We'll tell you if your guess was too high or too low.</p>
    
        <div class="form">
            <label for="guessField">Enter a guess: </label>
            <input type="text" id="guessField" class="guessField">
            <input type="submit" value="Submit guess" class="guessSubmit">
        </div>
    
        <div class="resultParas">
            <p class="guesses"></p>
            <p class="lastResult"></p>
            <p class="lowOrHi"></p>
        </div>
    
    
    </body>
    
    </html> 
    
  • Gourav Thakur
    Gourav Thakur over 5 years
    I think I am doing something wrong. Putting <script> at bottom didn't resolve the problem. Now there are 2 errors. : "Uncaught SyntaxError: Identifier 'randomNumber' has already been declared"
  • nCardot
    nCardot over 3 years
    Better yet, keep the script link in the head but add the defer attribute.