14

How to I consume the Promise.all fetch api json data? It works fine to pull it if I don't use Promise.all. With .all it actually returns the values of the query in the console but for some reason I'm not able to access it. Here is my code and how it looks in the console after it resolves.

Promise.all([
    fetch('data.cfc?method=qry1', {
        method: 'post',
        credentials: "same-origin", 
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: $.param(myparams0)
    }),
    fetch('data.cfc?method=qry2', {
        method: 'post',
        credentials: "same-origin", 
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: $.param(myparams0)
    })
]).then(([aa, bb]) => {
    $body.removeClass('loading');
    console.log(aa);
    return [aa.json(),bb.json()]
})
.then(function(responseText){
    console.log(responseText[0]);

}).catch((err) => {
    console.log(err);
});

All I want is to be able to access data.qry1. I tried with responseText[0].data.qry1 or responseText[0]['data']['qry1'] but it returned undefined. This below is the output from console.log responseText[0]. The console.log(aa) gives Response {type: "basic" ...

    Promise {<resolved>: {…}}
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: Object
data: {qry1: Array(35)}
errors: []
VLAZ
  • 26,331
  • 9
  • 49
  • 67
Dong
  • 328
  • 1
  • 3
  • 16
  • Does this answer your question? [How can I fetch an array of URLs with Promise.all?](https://stackoverflow.com/questions/31710768/how-can-i-fetch-an-array-of-urls-with-promise-all) – Ivar May 27 '21 at 08:00

6 Answers6

21

The simplest solution would be to repeat the use of Promise.all, to just wait for all .json() to resolve. Just use :

Promise.all([fetch1, ... fetchX])
.then(results => Promise.all(results.map(r => r.json())) )
.then(results => { You have results[0, ..., X] available as objects })
Simon G
  • 16
  • 1
  • 3
adyry
  • 613
  • 6
  • 15
15

Aparently aa.json() and bb.json() are returned before being resolved, adding async/await to that will solve the problem :

.then(async([aa, bb]) => {
    const a = await aa.json();
    const b = await bb.json();
    return [a, b]
  })

Promise.all([
    fetch('https://jsonplaceholder.typicode.com/todos/1'),
    fetch('https://jsonplaceholder.typicode.com/todos/2')
  ]).then(async([aa, bb]) => {
    const a = await aa.json();
    const b = await bb.json();
    return [a, b]
  })
  .then((responseText) => {
    console.log(responseText);

  }).catch((err) => {
    console.log(err);
  });

Still looking for a better explaination though

Taki
  • 17,320
  • 4
  • 26
  • 47
  • aa & bb are the response objects from the resolved requests. `.json()` is async itself and returns a promise with the resolved body content. https://developer.mozilla.org/en-US/docs/Web/API/Body/json – lecstor Feb 27 '19 at 01:53
2

I came across the same problem and my goal was to make the Promise.all() return an array of JSON objects.

let jsonArray = await Promise.all(requests.map(url => fetch(url)))
    .then(async (res) => {
        return Promise.all(
            res.map(async (data) => await data.json())
        )
    })

And if you need it very short (one liner for the copy paste people :)

const requests = ['myapi.com/list','myapi.com/trending']
const x = await Promise.all(requests.map(url=>fetch(url))).then(async(res)=>Promise.all(res.map(async(data)=>await data.json())))
BotDamian
  • 29
  • 7
1

Instead of return [aa.json(),bb.json()] use return Promise.resolve([aa.json(),bb.json()]). See documentation on Promise.resolve() .

Alex Pappas
  • 2,377
  • 3
  • 24
  • 48
0

You can just throw await in front of your Promise instead of awaiting each individual fetch

await Promise.all([
    fetch('https://jsonplaceholder.typicode.com/todos/1'),
    fetch('https://jsonplaceholder.typicode.com/todos/2')
  ]).then(async([aa, bb]) => {
    const a =  aa.json();
    const b =  bb.json();
    return [a, b]
  })
  .then((responseText) => {
    console.log(responseText);

  }).catch((err) => {
    console.log(err);
  });

Hope this helps

Vash
  • 141
  • 11
-1

Using Promise.all to fetch the json responses of each of the API's-

CODE:

Promise.all([
  API_1_Promise,
  API_2_Promise,
  API_3_Promise])
  .then(allResults => console.log(allResults))
  .catch(err => console.log(err))

In which API_1_Promise,API_2_Promise,API_3_Promise is defined as

API_1_Promise = fetch(`API_URL_1`, {  *Add required headers* }).then(response => response.json())

API_2_Promise = fetch(`API_URL_2`, {  *Add required headers* }).then(response => response.json())

API_3_Promise = fetch(`API_URL_3`, { *Add required headers* }).then(response => response.json())

RESPONSE: This will print the array of responses from all the API calls In console-->

[JSON_RESPONSE_API1, JSON_RESPONSE_API2, JSON_RESPONSE_API3]
Rishabh Saxena
  • 274
  • 2
  • 6