Getting Error When Trying to Loop Through a JSON Array of Objects

I am trying to loop through a JSON response from a Web API inside of the Fetch API. When I do a console log I am getting the following JSON string from the Web API response

{
  "data": "[{\"Name\":\"Flower.jpg\"},{\"Name\":\"kitten.jpg\"}]"
}

However, when I try to loop through this response using the forEach loop it says that data.forEach is not a function. I tried using JSON.parse but that also failed. the following is my fetch api code.

 fetch('https://localhost:7209/api/Main/GetFiles')
     .then(res => {
         if (!res.ok) {
             throw new Error("Cannot fetch resource!")
         }
         return res.json()
     })
     .then(data => {
         data.forEach(file => {
             const markup = `<li>${file.Name}</li>`;
             document.querySelector('dialog ul').insertAdjacentHTML('beforeend', markup);
         });
     }).catch(error => console.log(error));

You forgot to json decode the data

1 Like

You don’t need to manually decode the response data when using fetch. The fetch API and the res.json() method take care of it for you.

You might want to use console.log to see where the issue is?

fetch('http://localhost:7209/api/Main/GetFiles')
  .then(res => {
    console.log('Response:', res);
    if (!res.ok) {
      throw new Error(`Cannot fetch resource! Status code: ${res.status}`);
    }
    return res.json();
  })
  .then(data => {
    console.log('Received data:', data);
    // ...
  })
  .catch(error => {
    console.error('Error fetching data:', error);
  });

Since you are returning a string that happens to be formatted as a JSON array (a list of dictionaries), but it’s still just a string until you parse it.

You have to do the following:

function getData() {
    fetch('http://localhost:5000/test')
        .then(res => {
            if (!res.ok) {
                throw new Error("Cannot fetch resource!")
            }
            return res.json()
        })
        .then(data => {
            const arrayObject = JSON.parse(data.data)
            arrayObject.forEach(file => {
                console.log(file.Name)
            });
        }).catch(error => console.log(error));
}

My test

3 Likes

For that matter, save your code the lookup time and predefine your target element, rather than querySelector-ing the same element multiple times inside a loop.

1 Like

Thank you everyone for your replies. This line const arrayObject = JSON.parse(data.data) arrayObject.forEach(file => { is the one that did the trick. I previously tried using JSON parse inline without setting it to a variable but it didn’t work.

Normally I would predefine my target elements but this is a special use case where I get the names and paths of all images from the image folder in the web server to populate a popup on a webpage. Then the user can select any image in the popup to be the source of any existing image on the web page. Of course I will then need to update the page source on the server to make this change permanent. I can also optimize the code by caching the api data.