Home > Software engineering >  Firestore promise wait for product details before returning products
Firestore promise wait for product details before returning products

Time:04-25

I know similar questions like this have been asked 1000 times but for the life of me I am struggling with something I feel is quite simple.

We have 2 tables, one called order_lines the other called order_lines_meta, I need to first query order_lines and for each line get the order_lines_meta and return that

I have tried a lot of variations, here is where I am at and stuck, I need it to wait for the order_lines_meta to come back because otherwise I get blank metaData as the data comes after nodejs has already outputted the order_lines

At the end an object that contains order info, line items of objects and within line items a meta data object

Appreciate the help, I just can't seem to wrap my brain on this one , and I am certainly open to other ways of doing this as well

Using nodejs, express, typescript, firestore

const orderNumber = req.query.orderNumber as string;
const customerName = req.query.customerName as string;
const orderDate = req.query.orderDate as string;

const pickListObj = {
      orderNumber: orderNumber,
      customerName: customerName,
      orderDate: orderDate,
      line_items: <any>[],
    };

db.collection('order_lines').where('number', '==', orderNumber).get().then((snap) => {
      const promises = <any>[];

      snap.forEach(async (order: any) => {
      // get meta data
        const metaDataObj = <any>[];
        const productName = order.data().name;
        const productQty = order.data().quantity;

        promises.push(db.collection('worder_line_meta').where('lineId', '==', order.data().lineId).get().then((doc: any) => {
          if (doc.display_value != '') {
            const meta = [{display_key: doc.data().display_key, display_value: doc.data().display_value}];
            metaDataObj.push(meta);
          }
        }));
      });
      return Promise.all(promises);
    }).then(() => {
      pickListObj.line_items.push({name: productName, quantity: productQty, meta_data: metaDataObj});
    });

CodePudding user response:

Move the push statement from the last .then inside the previous .then:

promises.push(db.collection('worder_line_meta')...then((doc: any) => {
  if (doc.display_value != '') {
    ...
  }
  pickListObj.line_items.push({name: productName,
                               quantity: productQty,
                               meta_data: metaDataObj});
}));

In the last .then, you will then find the complete pickListObj.

However, I wonder whether it might be simpler and faster to join the two database collections right on the database and retrieve everything with one db.collection operation.

  • Related