1

I have a problem with using fetchs, I have an array of urls that have a JSON content, I want to get the data from all these JSON's and display them in html.

With 1 url I get the result I want:

fetch('myurl1')
.then(response => response.json())
.then(data => {
  let element = document.querySelector('.ele');
  element.innerHTML = `<p>${data.title}</p>`
})
.catch(err => console.log(err))

But when I have several urls I do not know what to do, I want to display the title that it has in all these json files, how do?

Promise.all(urlsArray.map(url =>
  fetch(url)))
  .then(responses => {
    responses.forEach(response => {
      response.json();
      
      let element = document.querySelector('.ele');
      element.innerHTML = `<p>${?????.title}</p>`
    })
  })
  .catch(err => console.log(err))

This is the way I was trying, I do not know how.

PS: .ele is a div

0

3 Answers 3

2

Collect all the results and then render them in whichever HTML form you like e.g.

Promise.all(urls.map(x => fetch(x))
  .then(async responses => {
    const results = await Promise.all(responses.map(x => x.json()));
    const html = results.map(x => `<li>${x.title}</li>`);
    let element = document.querySelector('.ele');
    element.innerHTML = `<ul>${html.join('')}</ul>`;
  })
  .catch(err => console.log(err))

This would result in:

<div class="ele">
  <li>Title A</li>
  <li>Title B</li>
  ...
</div>
Sign up to request clarification or add additional context in comments.

5 Comments

@Bergi it won't really impact the code, then returns a Promise regardless. This just allows the code to be more succinct rather than introducing an additional then
What about a forEach loop by putting urls in an array?
@weegee No, forEach is not a good idea. map does it much better.
@weegee as Bergi said, forEach with an IO bound call won't guarantee any sort of order, whereas collecting the data first and then processing allows for more control.
0

You can do the same thing as before, using map on the responses to create an array of Promises that resolve to the parsed json data:

Promise.all( urlsArray.map(url =>fetch(url)) )
  .then(responses => {
    return Promise.all(responses.map(response => response.json()))
  })
  .then(dataArray => {
    dataArray.forEach(data => {
      let element = document.querySelector('.ele');
      element.innerHTML = `<p>${data.title}</p>`
    })
  })
  .catch(err => console.log(err))

Comments

0

I'd suggest putting all your URLs inside an array and then do a forEach on them one by one and run your methods easily. This won't guarantee an order but will for sure. Don't forget to handle errors

// define our fetch function here just for an example
let fetch = (url) => new Promise(res => setTimeout(() => res(url + " is Fetched"),1000))

let urls = ['url1', 'url2', 'url3'] // all your urls in an array
urls.forEach(url => { // for every url inside the array
  fetch(url) // fetch the url
    .then(data => { // then append them to the document
      var node = document.createElement("LI");
      var textnode = document.createTextNode(data);
      node.appendChild(textnode);
      document.getElementsByTagName("body")[0].appendChild(node)
    })
})

1 Comment

This does not guarantee any order in which the results are appended to the DOM. Also, you should always handle errors on the end of a promise chain.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.