Mr CEO
Mr CEO

Reputation: 49

How do I update the DOM using JavaScript fetch method to filter user data from API?

I am looking to GET Data from API and display in HTML page using JavaScript fetch function. The JavaScript codes are detailed below. I can read the console.log of the user data from API. However, nothing is displayed on the HTML page as expected.


    <script>
      fetch('https://dummyjson.com/user')
        .then(response => response.json())
        .then(data => console.log(data));
    </script>

I can't seem to figure out what is missing.

Screenshot 1: Data API

I have added a loop function to retrieve and filter the API data and insert the result into HTML tag as detailed below:

    <script>
      fetch('https://dummyjson.com/user')
        .then(result => {
          return result.json();
        })
        .then(data => console.log(data))
        .then(data => {
          data.forEach(user => {
            const show = `<p>${user.firstName}</p>`;
            let html = document.querySelector('item');
            html.insertAdjacentHTML('after begin', show);
          });
        });
    </script>

Screenshot 2: Console.log results

Expected result should have been the first names (firstName) of all the user.

When the code runs, output does not display the expected result in the HTML page. The console log does not show any errors. Simply a blank page.

Complete Code Below:


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <style>
          body {
        background: transparent;
        color: #2c0493;
        padding: 44px;
        margin: 0;
        height: 100vh;
        align-items: center;
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
          Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
      }

      h3,
      h2 {
        margin: 0;
      }
    </style>
  </head>
  <body>
    <h2 id="header">GET Data from API</h2>
    <h3>And display in HTML with JavaScript</h3>
    <hr />
    <div id="item"></div>
    <script>
      fetch('https://dummyjson.com/user')
        .then(result => {
          return result.json()
        })
        .then(data => console.log(data))
        .then(data => {
          data.forEach(user => {
            const show = `<p>${user.firstName}</p>`
            let html = document.querySelector('item')
            html.insertAdjacentHTML('afterbegin', show)
          });
        });
    </script>
  </body>
</html>

More Screenshots here:

Screenshot 3: No HTML output

Expected output:

Screenshot 4: Expected output

Upvotes: 0

Views: 173

Answers (3)

Jaromanda X
Jaromanda X

Reputation: 1

Firstly, lets address the issues in your code

  1. .then(data => console.log(data)) means the next .then receives undefined as the argument
  2. the data is not an array, the array is data.users
  3. when getting an id in .querySelector, since it's CSS syntax, you need a # in the selector, e.g. #item
  4. in .insertAdjacentHTML the first argument is one of beforebegin|afterbegin|beforeend|afterend ... there is no space in this value

One thing to note, since you use .afterbegin the list will be shown in reverse order to the data you receive - that may be your intention, if not, you would use beforeend in .insertAdjacentHTML

Fixing your code, so it works:

fetch('https://dummyjson.com/user')
  .then(result => result.json())
  .then(data => {
    console.log(data);
    return data;
  }) // 1. keep the data flowing in the chain
  .then(data => {
    data.users.forEach(user => { // 2. data.users is the array you are after
      const show = `<p>${user.firstName}</p>`;
      let html = document.querySelector('#item'); // 3. note the `#`
      html.insertAdjacentHTML('afterbegin', show); // 4. no space in afterbegin
      // note, this will display users in reverse order w.r.t. data.users
    });
  })
<p id="item"></p>

Let's do modern version, note the async function would not be needed in a <script type="module"> since that allows top level await

async function getData() {
  const target = document.querySelector('#item');
  const result = await fetch('https://dummyjson.com/user');
  const data = await result.json();
  console.log(data);
  // remove the this     .reverse() below if you didn't mean to reverse the order
  const html = data.users.reverse().map(({firstName}) =>`<p>${firstName}</p>`).join("");
  target.insertAdjacentHTML('afterbegin', html);
}
getData();
<p id="item"></p>

Upvotes: 2

IT goldman
IT goldman

Reputation: 19440

You do array foreach but not on the correct array.

should be something like:

fetch('https://dummyjson.com/user')
  .then(result => {
    return result.json()
  })
  .then(data => console.log(data))
  .then(data => {
    data.users.forEach(user => {
      const show = `<p>${user.firstName}</p>`
      let html = document.querySelector('item')
      html.insertAdjacentHTML('afterbegin', show)
    });
  });

Upvotes: 1

PekosoG
PekosoG

Reputation: 264

According to the querySelector() documentation:

The Document method querySelector() returns the first Element within the document that matches the specified CSS selector, or group of CSS selectors. If no matches are found, null is returned. Blockquote

https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector

You can use getElementById() to achieve the desired result with something like

let html = document.getElementById("item");
html.innerHTML = "<p>whatever you want<p>"

https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById

Upvotes: 0

Related Questions