Uncaught (in promise) TypeError: Cannot set property 'innerHTML' of null - I can see value in console.log()

This is my very first post so, apologies in advance. The goal of this project is to develop a web app that can be used to fetch users from https://api.github.com/users and list their details along with repo information. I am having a problem with my forEach() in my add_user_repos() function. The function works on the first click but not the second. Below is my code for a web app. I am getting a 'Uncaught (in promise) TypeError: Cannot set property 'innerHTML' of null' error on the bolded line. I have used console.log(repo.name) and it prints. Any feedback on the problem or my code in general will be greatly appreciated, thanks in advance.

function search_user() {

  const url = 'https://api.github.com/users/';
  const name = document.forms["search_bar"]["search"].value;
  get_user_details(name);

  async function get_user_details(input) {
    const headers = {
      //token
    }

    const resp = await fetch(url + input, {
      "method": "GET",
      "headers": headers
    });

    const data = await resp.json();
    addData(data);
  }

  function addData(data) {
    const user_name = document.getElementById("name");
    const user_username = document.getElementById("username");
    const user_email = document.getElementById("email");
    const user_location = document.getElementById("location");
    const user_picture = document.getElementById("picture");
    const user_gists = document.getElementById("gists");
    const pic = new Image();

    pic.src = data.avatar_url;
    user_picture.appendChild(pic);
    user_name.innerHTML = data.name;
    console.log(data.name);
    user_username.innerHTML = data.login;
    user_email.innerHTML = data.email;
    user_location.innerHTML = data.location;
    user_gists.innerHTML = data.public_gists;

    get_user_repos(data.login);

    async function get_user_repos(username) {
      const resp = await fetch(url + username + "/repos");
      const repo_data = await resp.json();
      add_user_repos(repo_data);
    }

    function add_user_repos(repos) {

      // counter used to find if more than 5 repos are added
      let counter = 0;

      const repo_div = document.getElementById("user_repos");

      repos.forEach((repo) => {
        let repo_name = document.getElementById("name" + counter);
        let repo_desc = document.getElementById("desc" + counter);

        // if more than 5 repo names/desc are added
        if (counter > 4) {
          const create_repo_name = document.createElement("p");
          const create_desc = document.createElement("p");

          create_repo_name.innerHTML = "<b>Name: </b>" + repo.name;
          create_desc.innerHTML = "<b>Description: </b>" + repo.description;
          create_desc.setAttribute("class", "row");
          repo_div.appendChild(create_repo_name);
          repo_div.appendChild(create_desc);

          // add scrolling
          document.getElementById("user_repos").style.overflow = "auto";
        } else {
          repo_name.innerHTML = repo.name;
          repo_desc.innerHTML = repo.description;
          repo_name.setAttribute("id", "row" + counter);
          repo_desc.setAttribute("id", "desc" + counter);
          counter++;
        }
      })
    }
  }
}
<!DOCTYPE html>
<html lang="en">

<head>

  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Title</title>
  <link rel="stylesheet" href="problem_3.css">



</head>

<body>
  <div class="center">
    <div class="section">
      <form name="search_bar">
        <label for="search"></label>
        <input id="search" type="text" name="search" placeholder="Username">
        <button type="button" onclick="search_user()">Search</button>
      </form>
    </div>
  </div>

  <div>
    <div class="container">
      <h1>User Profile</h1>
      <div class="wrapper">
        <div id="picture">
          <!-- image -->
        </div>
        <div id="user_info">
          <table>
            <tr>
              <th>Name: </th>
              <td id="name"></td>
            </tr>
            <tr>
              <th>Username: </th>
              <td id="username"></td>
            </tr>
            <tr>
              <th>Email: </th>
              <td id="email"></td>
            </tr>
            <tr>
              <th>Locations: </th>
              <td id="location"></td>
            </tr>
            <tr>
              <th>Number of gists: </th>
              <td id="gists"></td>
            </tr>
          </table>
        </div>
      </div>
    </div>

  </div>

  <div class="container">
    <h1>User Repos</h1>
    <div class="wrapper">
      <div id="user_repos">
        <div class="user_repos">
          <table id="repo">
            <tr>
              <th>Name: </th>
              <td id="name0"></td>
            </tr>
            <tr>
              <th>Description: </th>
              <td id="desc0"></td>
            </tr>
            <tr>
              <th>Name: </th>
              <td id="name1"></td>
            </tr>
            <tr class="row">
              <th>Description: </th>
              <td id="desc1"></td>
            </tr>
            <tr>
              <th>Name: </th>
              <td id="name2"></td>
            </tr>
            <tr class="row">
              <th>Description: </th>
              <td id="desc2"></td>
            </tr>
            <tr>
              <th>Name: </th>
              <td id="name3"></td>
            </tr>
            <tr class="row">
              <th>Description: </th>
              <td id="desc3"></td>
            </tr>
            <tr>
              <th>Name: </th>
              <td id="name4"></td>
            </tr>
            <tr class="row">
              <th>Description: </th>
              <td id="desc4"></td>
            </tr>
          </table>
        </div>
      </div>
    </div>
  </div>
</body>

</html>

2 answers

  • answered 2020-10-29 22:40 A.DUPONCHEL

    TypeError: Cannot set property 'innerHTML' of null'
    

    The issue is related to repo_name variable, not repo.name.

    document.getElementById("name" + counter); returns null

    You should ensure "name" + counter exists in your DOM.

  • answered 2020-10-29 23:11 Eugen Sunic

    Instead of setting the node element to have an id of "row"+ counter

    repo_name.setAttribute("id", "row" + counter);

    set it to have an id of "name" + counter

    repo_name.setAttribute("id", "name" + counter);

    Thereby in the next searches you will again be able to find that element in the DOM.