Home > Software design >  Function addEventListener doesn't work with Fetch
Function addEventListener doesn't work with Fetch

Time:01-04

What I am doing:
I am making a portfolio for me, using HTML, CSS and JavaScript pure. I am creating projects page and trying create a <p> with JavaScript and inserting data from a .json file, but:

What's the problem?
The Fetch API doesn't working with addEventListener.

I had tried:
Create the <p> first and out of addEventListener function insert the data, but also doesn't work.

Part of JavaScript:

async setProjects(){
  let response = await fetch("contents/projects.json");
  let responseJson = await response.json();
    
  document.addEventListener("DOMContentLoaded", function () {
    var p = document.createElement('p');
    
    p.innerHTML = responseJson.one.bio;
    p.id = "bio-project";
    // p.style.cssText = 'border-left: 8px solid aqua;';
    
    document.querySelector(".projeto-contents").appendChild(p);
  }, false)
}

HTML:

<!DOCTYPE html>
<html lang="pt-br">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Projetos - Vitor Hugo's Portifolio</title>
    <link rel="stylesheet" href="../style.css" />
    <script type="text/javascript" src="script.js"></script>
  </head>

  <body>
    <header>
      <nav>
        <a  href="/">Vitor Hugo</a>
        <div >
          <div ></div>
          <div ></div>
          <div ></div>
        </div>
        <ul >
          <li><a href="index.html">Home</a></li>
          <li><a href="sobre.html">Sobre</a></li>
          <li><a href="projetos.html">Projetos</a></li>
          <li><a href="contatos.html">Contato</a></li>
        </ul>
      </nav>
    </header>
    <script src="../mobile-screen.js"></script>

    <!--  -->
    <div >
      <div >
        <h1 id="titulo-project">test</h1>
      </div>
    </div>
    <script language="javascript">
      const portifolio = new Portifolio();
      portifolio.setProjects();
    </script>
  </body>
</html>

JSON:

{
  "one":{
    "name":"Lorem",
    "bio":"Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos dolore pariatur accusamus quaerat hic distinctio, cum, ratione dignissimos, doloremque incidunt provident deleniti consectetur qui alias quam quod porro error temporibus.",
    "language":"Python"
  },
  "two":{
    "name":"testname2",
    "bio":"testbio2",
    "language":"testlanguage2"
  },
  "three":{
    "name":"testname3",
    "bio":"testbio3",
    "language":"testlanguage3"
  },
  "four":{
    "name":"testname4",
    "bio":"testbio4",
    "language":"testlanguage4"
  }
}

Project link: https://github.com/vitorhugo1207/portfolio

What I have to do? please help me. And one more thing: about json is possible to use number as index? And sorry for any error orthography and grammar I am studing English.

CodePudding user response:

async/await allows you to write code that looks like it's synchronous, but it isn't really -- it's just syntactic sugar for working with promises.

After fetch() sends the AJAX request, the browser continues loading the document. By the time it finishes, the DOM has been loaded and the DOMContentLoaded event has alrady fired, so it's too late to add an event listener for it.

You can get the promise from fetch() and use its .then() method from within the DOMContentLoaded listener.

setProjects() {
  let response_promise = fetch("contents/projects.json");

  document.addEventListener("DOMContentLoaded", function() {
    response_promise.then(response => response.json().then(responseJson => {
      var p = document.createElement('p');

      p.innerHTML = responseJson.one.bio;
      p.id = "bio-project";
      // p.style.cssText = 'border-left: 8px solid aqua;';

      document.querySelector(".projeto-contents").appendChild(p);
    }))
  }, false)
}

CodePudding user response:

document.addEventListener("DOMContentLoaded", async () => {
  const response = await fetch("contents/projects.json").then((res) => res.json());
  const paragraph = document.createElement("p");
  paragraph.innerHTML = response.one.bio;
  paragraph.id = "bio-project";
  // p.style.cssText = 'border-left: 8px solid aqua;';

  document.querySelector(".projeto-contents").appendChild(paragraph);
});
<!DOCTYPE html>
<html lang="pt-br">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Projetos - Vitor Hugo's Portifolio</title>
    <link rel="stylesheet" href="../style.css" />
    <script defer src="./index.js"></script>
  </head>

  <body>
    <header>
      <nav>
        <a  href="/">Vitor Hugo</a>
        <div >
          <div ></div>
          <div ></div>
          <div ></div>
        </div>
        <ul >
          <li><a href="index.html">Home</a></li>
          <li><a href="sobre.html">Sobre</a></li>
          <li><a href="projetos.html">Projetos</a></li>
          <li><a href="contatos.html">Contato</a></li>
        </ul>
      </nav>
    </header>

    <div >
      <div >
        <h1 id="titulo-project">test</h1>
      </div>
    </div>
  </body>
</html>

You're firing DOMContentLoaded after DOM was already rendered to your page. Also in your HTML in you're using without defer attribute. Basically defer is telling browser to execute that script after document has been parsed or you can just append it at the of the body <script src="./index.js"></script> .

Also i'm using Promise API, if you want to know more about it check PromiseAPI or about async/await

  •  Tags:  
  • Related