'Iterate through a nested array of objects in javaScript

When I load my html page, I have this returned:

id: country url: http://data:8004/v1/entity/country name: countries description: All the countries in the world

id: states url: http://data:8004/v1/entity/states name: states data description: A catalog of all data

When I click on the link, I get something like this:

id: edbee2d36f35810d677085f6ec62e7153e96a423fa88b8d5ff2d473de0481e49
url:http://data:8004/v1/entity/county/edbee2d36f35810d677085f6ec62e7153e96a423fa88b8d5ff2d473de0481e49
type: country, 
name: London, 
legal: [object Object]

It doesn't return the data in the Legal [{}].

This is what the json looks like:

[
    {
        "id": "edbee2d36f35810d677085f6ec62e7153e96a423fa88b8d5ff2d473de0481e49",
        "url": "http://data:8004/v1/entity/county/edbee2d36f35810d677085f6ec62e7153e96a423fa88b8d5ff2d473de0481e499",
        "type": "country",
        "name": "London",
        "legal": [
            {
                "type": "attribution",
                "link": "https://en.wikipedia.org/"
            }
        ]
    },

How can I loop through the nested array to access and retrieve legal[{}]? Also, when i click on a URL, it returns my results, and when I click on another one, it moves the previous results down and positions the new one on top without clearning the old one. I tried using ```results.innerHTML=';" but it still didn't clear the dom before loading new results.

This is my code:


const createElement = (tag, ...content) => {
    const el = document.createElement(tag);
    el.append(...content);
    return el;
  };
  
  const setData = (entity) =>{
      console.log(JSON.stringify(entity))
      let entityProps = Object.keys(entity)
      console.log(entityProps)
  const dl = document.createElement('dl');

  entityProps.forEach(function(prop) {
 
    const pre_id =  document.createElement('pre');

    const dt_id =  document.createElement('dt');
    dt_id.textContent = prop;

    pre_id.appendChild(dt_id);
  
    const dd_id =  document.createElement('dd');
    

    if (prop == "url") {
        const link = document.createElement('a');
        link.textContent = entity[prop];
        link.setAttribute('href', '#')
        link.addEventListener('click',function(e) {
      console.log("I'm working!")
      console.log(e.target.innerHTML)
      RetrieveData(e.target.innerHTML)
  });
  dd_id.appendChild(link);

    } else {
        dd_id.textContent = entity[prop];

    }

    pre_id.appendChild(dd_id);
  
    dl.appendChild(pre_id);

    
  });



  return dl;
  
  }

    const results = document.getElementById("results");


function RetrieveData(url){
   
    fetch(url
    , {
        headers:{
      'x-data': '78shjjhsjja-95ff-a6c0396bd619.b77738aa-f798-4bb9-93c4-914c5c83608c',
      'x-access': 'access-data',
      
    },
})
.then((res) => (res.ok ? res.json() : Promise.reject(res)))
  .then((data) => {
    results.append(
        ...data.flatMap((entry) => [
            setData((entry)),
          document.createElement("br"),
          document.createElement("br"),
        ])
      );
  })
  .catch(console.error);
}


const data=document.getElementById("data");

catalog.addEventListener("onclick",  RetrieveData(`http://data:8004/v1/entity/`));


Solution 1:[1]

You are setting the value of the properties that are not 'url' to be the value of the JS object. This is the relevant part of your code.

 if (prop == "url") {
        const link = document.createElement('a');
        link.textContent = entity[prop];
        link.setAttribute('href', '#')
        link.addEventListener('click',function(e) {
      console.log("I'm working!")
      console.log(e.target.innerHTML)
      RetrieveData(e.target.innerHTML)
  });
  dd_id.appendChild(link);

    } else {
        dd_id.textContent = entity[prop];

    }

You have there to make an special case for legal too, then you have two options:

  • To JSON.stringify the legal property
  • To process the values inside of legal as you are doing with the countries

A simple implementation of the JSON.stringify solution:

 if (prop == "url") {
        const link = document.createElement('a');
        link.textContent = entity[prop];
        link.setAttribute('href', '#')
        link.addEventListener('click',function(e) {
          console.log("I'm working!")
          console.log(e.target.innerHTML)
          RetrieveData(e.target.innerHTML)
        });
        dd_id.appendChild(link);

    } if (prop == "legal") {
        dd_id.textContent = JSON.stringify(entity[prop]);
    }else {
        dd_id.textContent = entity[prop];
    }

About not clearing your results it could be that you are always appending new elements but it isn't easy to follow without a testing environment.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Pablo Carrillo Alvarez