1

I would like to make two api call's at once to a ReST API in my vue component. I have done research online and am using this logic:

// Multiple fetches
      Promise.all([
        fetch(
          `https://api.covid19api.com/live/country/${this.selected}/status/confirmed/date/${this.yesterday}`
        ),
        fetch(
          `https://api.covid19api.com/live/country/south-africa/status/confirmed/date/2020-03-21T13:13:30Z`
        )
      ])
        .then(responses => {
          // Get a JSON object from each of the responses
          return responses.map(response => {
            return response.json();
          });
        })
        .then(data => {
          // Log the data to the console
          // You would do something with both sets of data here

          this.coronaVirusStats1 = data[0];
          console.log(this.coronaVirusStats1);
        })
        .catch(function(error) {
          // if there's an error, log it
          console.log(error);
        });
    }

The consoled value is a promise which I understand but when I look in the Vue devTools under my component I see that coronaVirusStats1 has a value of "Promise", not the array of objects I expect back. When I do a single fetch and consume the data variable there is no problem. However I am perplexed as to how one accesses the returned data from fetch calls to multiple endpoints. I tried all the solutions here fetching api's ,but none worked. If someone can elucidate on the proper way to access the data from the fetches I would be most appreciative.

Phil
  • 157,677
  • 23
  • 242
  • 245
Alan
  • 1,067
  • 1
  • 23
  • 37

1 Answers1

3

You're just about there. The issue is that your first then returns an array of promises. Unfortunately, promise chains only work with a Promise instance so there's nothing here that will wait for your promises to resolve.

The quick fix is to change the first then to

return Promise.all(responses.map(r => r.json()))

That being said, there's a little more to the fetch API, particularly for dealing with errors.

I would use something like the following for each fetch call to make sure network errors and non-successful HTTP requests are handled correctly.

This will also handle unwrapping the JSON response so you don't have to use the above

Promise.all([
  fetch(url1).then(res => res.ok && res.json() || Promise.reject(res)),
  fetch(url2).then(res => res.ok && res.json() || Promise.reject(res))
]).then(data => {
  // handle data array here
})

See https://developer.mozilla.org/en-US/docs/Web/API/Response/ok

Phil
  • 157,677
  • 23
  • 242
  • 245
  • 1
    Thanks for a concise, well explained solution to the problem. Just when I think I got promises another use case throws me for a loop. I thought the first .then would wait for all responses to go thru .json() and then an array of data would pass to 2nd .then. Promises and this are truly the bain of JavaScript developers:) I would like to know how all the examples I saw from googling never address this aspect of multiple fetch request's. Stay safe. – Alan Apr 26 '20 at 23:46