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

13,409

Solution 1

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

Solution 2

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

Solution 3

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

Solution 4

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())))
Share:
13,409
Dong
Author by

Dong

Updated on June 19, 2022

Comments

  • Dong
    Dong almost 2 years

    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: []
    
  • lecstor
    lecstor about 5 years
    aa & bb are the response objects from the resolved requests. .json() is async itself and returns a promise with the resolved body content. developer.mozilla.org/en-US/docs/Web/API/Body/json