0

this doubt is about promises. I need to add documents of the subcollection 'bar' into array intialized outside of the block

...
foo.bars = new Array<IBar>();
let manyBars = documentRef.collection('bar').listDocuments();
(await manyBars).forEach( barItem => {
    barItem.get().then(barDocument => {

        let bar: IBar = JSON.parse(JSON.stringify(barDocument.data()));
        if (foo.bars !== null) {
            foo.bars.push(bar);
            console.log('in');
        }
    });
});

console.log('out');

My console.log() prints firts 'out' and then 'in'. What am I doing wrong? forEach method has "await".

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
destri
  • 21
  • 4
  • `get()` is also asynchronous and returns a promise. You won't be able to use await inside the forEach loop. You will need another strategy. See: https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop – Doug Stevenson Mar 21 '20 at 19:08
  • Thank you, I tried with Promise.all(...) and it worked perfect – destri Mar 22 '20 at 11:16

1 Answers1

1

What you are doing wrong is, chiefly, expecting asynchronous .then() callbacks to complete in the line-order it would if it were synchronous. It is important to realise that .then() callbacks are executed after the current event thread has completed.

Whilst await is just a syntactical alternative for .then(), it largely allows asynchronous code to be written much as it would be if it was synchronous.

In general, it's good practice, within any given function, not to mix .then() and await syntax

Assuming barDocument.data() is synchronous, it should be as simple as this ...

...
try{
    let manyBars = await documentRef.collection('bar').listDocuments();
    let barDocuments = await Promise.all(manyBars.map(barItem => barItem.get()));
    let foo.bars = barDocuments.map(barDocument => barDocument.data());
}
catch(error) {
    console.log(error);
    // handle error as necessary.
    // return a value or re-throw the error.
}

If barDocument.data() is asynchronous, then you will need to introduce another await Promise.all(...).

Roamer-1888
  • 19,138
  • 5
  • 33
  • 44