Home > Back-end >  Javascript loop json data into html forEach issue
Javascript loop json data into html forEach issue

Time:10-30

I'm trying to parse the json to html.

  • Looping the data with a forEach function has an issue. Not sure why?
  • also the values aren't displaying properly.
  • I'd like to be able to have the data displayed and looped into html.

async function fetchData() {

  const response = await fetch('https://assets.cmcmarkets.com/json/cmc-test-most-popular-feed.json');
  const data = await response.json();
  console.log(data)


  data.forEach(obj => {

    Object.entries(data).forEach(([key, value]) => {

      console.log(`${key} ${value}`);

      const Name = document.querySelector('.name'),
        Code = document.querySelector('.code'),
        Spread = document.querySelector('.spread'),
        CellA = document.querySelector('.cellA');


      if (key == "name") {
        Name.innerHTML = `<div>Name: ${value}</div>`;
      }

      if (key == "code") {
        Code.innerHTML = `<div>Code: ${value}</div>`;
      }

      if (key == "spread") {
        Spread.innerHTML = `<div>Spread: ${value}</div>`;
      } else if (key == "1day") {

      }

      //  data["X-ABFDN"]['1day']  data["X-ABAAA"]['1day']  data["X-AQWER"]['1day']
      else if (key == "1day") {
        CellA.innerHTML = `<div>movement: ${data[key]["movement"]}</div><div>price: ${data[key]["price"]}</div>`;

      }


    });


  });

}

fetchData();
<div class="name"></div>
<div class="code"></div>
<div class="spread"></div>
<div class="cellA"></div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Give this a try. Note that each time through the loop, you are replacing the previous iteration values with new content, which isn't ideal. You'll probably have to create new output elements for each iteration through the loop.

async function fetchData() {

  const response = await fetch('https://assets.cmcmarkets.com/json/cmc-test-most-popular-feed.json');
  const data = await response.json();
  console.log(data)

  Object.entries(data).forEach(([key, obj]) => {

    const Name = document.querySelector('.name'),
      Code = document.querySelector('.code'),
      Spread = document.querySelector('.spread'),
      CellA = document.querySelector('.cellA');
    
    Name.innerHTML = `<div>Name: ${obj.name}</div>`;
    Code.innerHTML = `<div>Code: ${obj.code}</div>`;
    Spread.innerHTML = `<div>Spread: ${obj.spread}</div>`;
    CellA.innerHTML = `<div>movement: ${obj.1day.movement}</div><div>price: ${obj.1day.price}</div>`;
  });
}

fetchData();

CodePudding user response:

You have two .forEach() loops on 'data' and on the containing objects. Both are objects, which you can not iterate directly. Use

Object.keys(obj)
Object.values(obj)
Object.entries(obj)

To get an iterable array with the data

In the snippet below this problem is solved an one object is displayed. But there is still a logical problem. You only have four divs, which you are refilling every round, so only the data of the last is seen in the end.

Won't correct this since I think the main issue is solved with this.

async function fetchData() {

  const response = await fetch('https://assets.cmcmarkets.com/json/cmc-test-most-popular-feed.json');
  const data = await response.json();
  console.log('data', data)

  Object.values(data).forEach(obj => {
    
    Object.entries(obj).forEach(([key, value]) => {

//       console.log(key, value);

      const Name = document.querySelector('.name'),
        Code = document.querySelector('.code'),
        Spread = document.querySelector('.spread'),
        CellA = document.querySelector('.cellA');


      if (key == "name") {
        Name.innerHTML = `<div>Name: ${value}</div>`;
      }

      if (key == "code") {
        Code.innerHTML = `<div>Code: ${value}</div>`;
      }

      if (key == "spread") {
        Spread.innerHTML = `<div>Spread: ${value}</div>`;
      } else if (key == "1day") {

      }

      //  data["X-ABFDN"]['1day']  data["X-ABAAA"]['1day']  data["X-AQWER"]['1day']
      else if (key == "1day") {
        CellA.innerHTML = `<div>movement: ${data[key]["movement"]}</div><div>price: ${data[key]["price"]}</div>`;

      }


    });


  });

}

fetchData();
<div class="name"></div>
  <div class="code"></div>
  <div class="spread"></div>
  <div class="cellA"></div>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

 async function fetchData() {

const response = await fetch('https://assets.cmcmarkets.com/json/cmc-test-most-popular-feed.json');
const data = await response.json();
//console.log(data)

//This is the line you are missing
const dataArray = Object.values(data)
console.log(dataArray)

dataArray.forEach(obj => {
  console.log(obj);

  const Name = document.querySelector('.name');
  const Code = document.querySelector('.code')
  const Spread = document.querySelector('.spread');
  const CellA = document.querySelector('.cellA');

  Name.innerHTML = `<div>Name: ${obj.name}</div>`;
  Code.innerHTML = `<div>Code: ${obj.code}</div>`;
  Spread.innerHTML = `<div>Spread: ${obj.spread}</div>`;
  //CellA.innerHTML = `<div>CellA: ${obj.1day.movement}</div>`;
  //For 1day never start your variable nams with a number
});



 }

  fetchData();

CodePudding user response:

value in itself is an object, so if you want to display it's name, you would use value.name. Remove one forEach level from your code and iterate through the keys/values of the retrieved data (where each value is an object).

With that in mind, one way to display data is to create a block of elements per object entry, using insertAdjacentHTML. Something like:

fetchData();

async function fetchData() {
  const data = await fetch(
      'https://assets.cmcmarkets.com/json/cmc-test-most-popular-feed.json' )
    .then( r => r.json() );
  
  Object.entries(data).forEach( ([key, value]) => 
    document.body.insertAdjacentHTML(`beforeend`, `
        <div >
          <div >Name: ${value.name}</div>
          <div >Code: ${value.code}</div>
          <div >Spread: ${value.spread}</div>
          ${value.cellA ? `<div >cellA: ${value.cellA}</div>` : ``}
          ${value["1day"] ? `
            <div >Movement: ${
              value["1day"].movement}</div>
            <div >Price: ${
              value["1day"].price || `unknown`}</div>` : ``}
        </div>`)
    );
}
body {
  margin: 2rem;
  font: 12px/15px verdana, arial;
}

.datablock {
  margin-bottom: 0.7rem;
}
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related