Dong
Dong

Reputation: 328

How to return the Promise.all fetch api json data?

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: []

Upvotes: 14

Views: 24040

Answers (6)

adyry
adyry

Reputation: 653

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 })

or, using async/await syntax, within async function body:

const promises = await Promise.all([fetch1, ... fetchX]);
const parsed = await Promise.all(promises.map(result => result.json()))

// You have parsed[0, ..., X] available as objects 

Upvotes: 24

BotDamian
BotDamian

Reputation: 39

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())))

Upvotes: 3

Vash
Vash

Reputation: 141

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

Upvotes: 0

Rishabh Saxena
Rishabh Saxena

Reputation: 274

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]

Upvotes: -1

Alex Pappas
Alex Pappas

Reputation: 2597

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

Upvotes: 1

Taki
Taki

Reputation: 17654

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

Upvotes: 16

Related Questions