Search code examples
vue.jsfetches6-promise

Making multiple api requests at once using fetch in vue


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.


Solution

  • 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