简体   繁体   English

方法在节点js中使用forEach循环进行云Firestore时给出空数组而不是完整数据

[英]method give null array instead of full data while using forEach loop in node js for cloud firestore

I want a Fully response in JSON like, 我想要JSON的完全响应,例如

[
   {
      "email":"a",
      "product":[
         {
            "price":100,
            "veg_name":"Potato",
            "stock":"10"
         },
         {
            "stock":"10",
            "price":"100",
            "veg_name":"Tomato"
         }
      ]
   },
   {
      "email":"amp",
      "product":[
         {
            "price":"1000",
            "veg_name":"ffdf"
         }
      ]
   }
]

This type of JSON data will store in fullDatas object in below code. 此类JSON数据将存储在以下代码中的fullDatas对象中。 on the fully completion of forEach loop. 完全完成forEach循环。 we can see this via console. 我们可以通过控制台看到这一点。 But, Response in always like, [] means null. 但是,Response总是像[]表示null。

let stockRef = firestore.collection('stock');
    const fullDatas = [];
    //stock
    let final = new Promise((resolve, reject) => {
        stockRef.get().then(documents => {
            documents.forEach(doc => {
                let data = {};
                //single select like 'a'
                data['email'] = doc.data()['email'];
                const product = [];

                let colRef = stockRef.doc(doc.id).collection('Product');
                colRef.get().then(vegDocs => {
                    vegDocs.forEach(veg => {
                        product.push(veg.data());
                    });
                    data['product'] = product;
                    fullDatas.push(data);
                    console.log(JSON.stringify(fullDatas));
                });
            });
            resolve(fullDatas);
        });
    });

    final.then((result) => {
        res.json(result);
    }).catch((error) => {
        res.send(error);
    });

What should I change in the above Code? 我应该在上述代码中进行哪些更改? I think I have implemented the wrong promise. 我认为我执行了错误的承诺。

I can't make a comment because of reputation rule. 由于声誉规则,我无法发表评论。 However, I think the wrong is in this line 但是,我认为这是错误的

data['email'] = doc.data()['email'];

regarding your code doc.data() is an array with 2 element and you bass the key 'email' without determining which element you are want to access, so I think you need to make another loop here. 关于您的代码doc.data()是一个包含2个元素的数组,并且您在未确定要访问哪个元素的情况下低音了'email'键,因此我认为您需要在此处进行另一个循环。

Rather using forEach and global/closure [] you can use Array.prototype.map . 可以使用Array.prototype.map而不是使用forEachglobal/closure []

You need to wait for each and every promise in the chain with return promise or await . 您需要等待链中的每个许诺,包括return promiseawait

when you get an array of promises back from .map you can use Promise.all to wait for each and every promise to be resolved. 当您从.map获得承诺的数组时,可以使用Promise.all等待每个承诺都得到解决。

import { promises } from "fs";

let stockRef = firestore.collection('stock');
//stock
let final = stockRef.get().then(documents => {
    return documents.map(doc => {
        let data = {};
        //single select like 'a'
        data['email'] = doc.data()['email'];
        let colRef = stockRef.doc(doc.id).collection('Product');
        return colRef.get().then(vegDocs => {
            const productPromises = vegDocs.map(veg => veg.data());
            return Promise.all(productPromises).then(product => data['product'] = product);
        }).then(() => data);
    });
}).then(Promise.all);

final.then((result) => {
    res.json(result);
}).catch((error) => {
    res.send(error);
});

By Reading a document reference. 通过阅读文档参考。 I have replacing forEach to for loop and also placed a proper async/await and proper use of Promise. 我已经将forEach替换为for循环,并且还放置了正确的异步/等待和Promise的正确使用。

let stockRef = firestore.collection('stock');
    const fullDatas = [];
    //stock
    let final = new Promise((resolve, reject) => {
        stockRef.get().then(async documents => {
            let docs = documents.docs;
            for (let doc of docs) {
                console.log(doc.data());
                let data = {};
                //single select like 'a'
                data['email'] = doc.data()['email'];
                const product = [];

                let colRef = stockRef.doc(doc.id).collection('Product');
                await colRef.get().then(vegSnapshot => {
                    let vegDocs = vegSnapshot.docs;
                    for (let veg of vegDocs) {
                        product.push(veg.data());
                    }
                    data['product'] = product;
                    fullDatas.push(data);
                    console.log(JSON.stringify(fullDatas));
                });
            }
            resolve(fullDatas);
        });
    });

    final.then((result) => {
        res.json(result);
    }).catch((error) => {
        res.send(error);
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM