0

First of all, there are some issues with console.log in Google Chrome not functioning as expected. This is not the case as I am working in VSCode.

  1. We begin with two async calls to the server.

    promise_a = fetch(url)
    promise_b = fetch(url)
    
  2. Since fetch results are also promises, .json() will needed to be called on each item. The helper function process will be used, as suggested by a Stackoverflow user -- sorry lost the link.

        let promiseResults = []

        let process = prom => {
            prom.then(data => {
               promiseResults.push(data);
            });
         };
  1. Promise.all is called. The resulting array is passed to .then where forEach calls process on item.json() each iteration and fulfilled promises are pushed to promiseResults.
        Promise.all([promise_a, promise_b])
          .then(responseArr => {
             responseArr.forEach(item => {
               process(item.json());
             });
          })              
  1. No argument is given to the final .then block because promiseResults are in the outer scope. console.log show confusing results.

    .then(() => {
    console.log(promiseResults); // correct results
    console.log(promiseResults[0]); // undefined ?!?
    })
    

Any help will be greatly appreciated.

adamb
  • 11
  • 2
  • Possible duplicate of [Google Chrome console.log() inconsistency with objects and arrays](https://stackoverflow.com/questions/24175017/google-chrome-console-log-inconsistency-with-objects-and-arrays) – Titus Jul 18 '19 at 06:05

2 Answers2

2

If you are familiar with async/await syntax, I would suggest you not to use an external variable promiseResults, but return the results on the fly with this function:

async function getJsonResults(promisesArr) {
    // Get fetch promises response
    const results = await Promise.all(promisesArr); 

    // Get JSON from each response promise
    const jsonResults = await Promise.all(results.map(r => r.json()));
    return jsonResults
}

This is usage example:

promise_a = fetch(url1)
promise_b = fetch(url2)

getJsonResults([promise_a, promise_b])
   .then(theResults => console.log('All results:', theResults))

Use theResults variable to extract necessary results.

Evgeny Melnikov
  • 952
  • 7
  • 13
1

You can try this, it looks the array loop is not going properly in the promise env. Specifically: the promiseResults is filled after you are logging.

var resultAll = Promise.all([promise_a, promise_b])
  .then(responseArr => {
     return Promise.all(responseArr.map(item => return item.json()));
  });

resultAll.then(promiseResults => {
   console.log(promiseResults);
});
3960278
  • 756
  • 4
  • 12
  • 2
    I think it should be `Promise.all(responseArr.map(item => process(item.json())))` – Titus Jul 18 '19 at 06:22
  • ya that should be the proper way, didn't try what i wrote but, Promise.all also takes usual array as iterable, not needed to be promise array. – 3960278 Jul 18 '19 at 06:24
  • This solution also works, and I love the simplicity of using Promise.all twice. Pushing to the external array was the wrong approach. Much thanks! – adamb Jul 18 '19 at 18:25