Wt.N
Wt.N

Reputation: 1658

How to avoid nested Promises to read from Firestore and wait for all resolve?

Problem

How to fix nested Promises and resolve all Promises?

I am reading from three firestore collections and do some calculation by resolved data.

Structure of firestore

/users/userId
/purchases/purchaseId/
  - userId: string
  - initialPrice: number
  - productId: string
/products/productId
  - itemId: string
  - currentPrice: number

Calculation I want to do

Calculate for each user
Σ(currentPrice[i] - initialPrice[i])
, where i is an item for each user.

Code that doesn't work and need fixed

db.collections('users').get().then(snap => {
  snap.forEach(user => {
    const userId = user.id
    let totalProfit = 0

    db.collections('purchases').where('userId', '===', userId).get().then(snap =>{
      snap.forEach(purchase => {
        const initialPrice = purchase.initialPrice
        const productId = purchase.productId

        db.collections('products').doc(productId).get().then(doc => {
          const currentPrice = doc.currentPrice
          const profit = currentPrice - initialPrice
          totalProfit += profit
        })
      })
    })
    // Please wait for all Promises resolved.
    console.log(userId, totalProfit)
  })
})

Upvotes: 2

Views: 68

Answers (1)

trincot
trincot

Reputation: 351369

Collect the inner promises and call Promise.all on them. Wait for that to resolve before calling console.log:

db.collections('users').get().then(snap => {
  snap.forEach(user => {
    const userId = user.id;
    let totalProfit = 0;

    db.collections('purchases').where('userId', '===', userId).get().then(snap =>{
      const promises = [];
      snap.forEach(purchase => {
        const initialPrice = purchase.initialPrice;
        const productId = purchase.productId;

        promises.push(db.collections('products').doc(productId).get().then(doc => {
          const currentPrice = doc.currentPrice;
          const profit = currentPrice - initialPrice;
          totalProfit += profit;
        }));
      });
      return Promise.all(promises);
    }).then(() => console.log(userId, totalProfit));
  });
});

Upvotes: 2

Related Questions