document.getElementById returns null on an existing element after a document.write

Question

Here is the full error message:

mlg.html:41 Uncaught TypeError: Cannot set property 'innerHTML' of null
  at ml (mlg.html:41)
  at HTMLButtonElement.onclick (mlg.html:9)

I was making a mad libs game and I was just doing a quick test to find bugs and then I stumbled across this problem. Here is the code:

<!DOCTYPE html>
<html>

<head>
</head>

<body>
  <button type="button" onclick="ml()">Mad Libs!</button>
  <p id="display"></p>

  <script>
    function ml() {
      var x = Math.floor((Math.random() * 10) + 1);

      //mad lib 1
      if (x == 1 || 2) {
        document.write("test1");
      }
      //mad lib 2
      if (x == 3 || 4) {
        document.write("test2");
      }
      //mad lib 3
      if (x == 5 || 6) {
        document.write("test3");
      }
      //mad lib 4
      if (x == 7 || 8) {
        document.write("test4");
      }
      //mad lib 5
      if (x == 9 || 10) {
        document.write("test5");
      }
      document.getElementById("display").innerHTML = x;
    }
  </script>
</body>
</html>

Show source
| javascript   | dom   | html   2017-01-07 02:01 1 Answers

Answers ( 1 )

  1. 2017-01-07 03:01

    Do not use document.write, it’s bad practice. It overwrites the entire page with test1, or some similar string. Therefore, when document.getElementById("display").innerHTML = x; is reached, no element with the ID of display will exist anymore and document.getElementById("display") will evaluate to null.

    If you want to test your if statements, use console.log("test1"); instead. Simply open the browser console (F12 in most browsers) and you’ll see the messages there.

    Speaking of your if statements: they’re wrong. if(test == 1 || 2) will always evaluate to true, because 2 is truthy. That’s not what you want. What you want is if(test == 1 || test == 2).

    Alternatives: if([1, 2].includes(test)), if([1, 2].indexOf(test) >= 0) (Check variable equality against a list of values).

◀ Go back