Search code examples
javascripthtmlfetch

HTML content is not added


I have a similar class structure and it doesn't work for me, I've already tried several things and can't fix the problem. As you can see, the constructors are executed correctly and also the method executed in the last constructor. However, when I create HTML content, it doesn't paint it. Why and how could you solve this?

class AutoComplete{
    constructor(){
    console.log("constructor autocomplete")
    this.table = new Table();
    
  }
}

class Table{
    constructor(){
    console.log("constructor table")
    
    this.arr = []
    
    fetch('https://jsonplaceholder.typicode.com/posts')
    .then((response) => response.json())
    .then((data) => {
        data.map(d => this.arr.push(d))
    });
  
    this.fill();
  }
  
  fill = () => {
    console.log("fill");
    const content = document.querySelector("#content");
    // doesn't work
    this.arr.forEach( ct => {
        const div = document.createElement("div");
        div.innerText = ct.body;
      
        content.appendChild(div);
        //content.innerHTML += div;
    });
  }
}

let autoc = new AutoComplete();
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title></title>
</head>
<body>
  
  <div id="content"></div>

</body>
</html>


Solution

  • This is happening because you need to call this.fill() within the .then() callback function. Otherwise. this.fill is called before you get data back from the API.

    Demo:

    class AutoComplete{
        constructor(){
        console.log("constructor autocomplete")
        this.table = new Table();
        
      }
    }
    
    class Table{
        constructor(){
        console.log("constructor table")
        
        this.arr = []
        
        fetch('https://jsonplaceholder.typicode.com/posts')
        .then((response) => response.json())
        .then((data) => {
            data.map(d => this.arr.push(d));
            this.fill();
        })
        
        // this.fill()
      }
      
      fill = () => {
        console.log("fill");
        const content = document.querySelector("#content");
        // doesn't work
        this.arr.forEach(ct => {
            const div = document.createElement("div");
            div.innerText = ct.body;
          
            content.appendChild(div);
            //content.innerHTML += div;
        });
      }
    }
    
    let autoc = new AutoComplete();
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width">
      <title></title>
    </head>
    <body>
      
      <div id="content"></div>
    
    </body>
    </html>