简体   繁体   中英

React Js Map function not working on a nested array

I am currently trying to learn ReactJS. For my projects I am getting data from firestore and then want to display on the screen.

Data in Firestore is stored as :

category: "Lemon"
currentUser:
  createdAt: October 21, 2020 at 2:52:25 PM UTC+5:30
  displayName: null
  email: "email@ymail.com"
id: "123"
dish: "vs"
image: "imageurl"
price: "8"

To retrieve this data I am using:

useEffect(() => {
  let m = [];
  var docRef = firestore.collection("Dish");
  docRef.get().then(function (querySnapshot) {
    querySnapshot.forEach(function (doc) {
      m.push({
        id: doc.id,
        category: doc.data().category,
      });
    });

    Setmida(m);

    Setmid(false);

    if (mid === false) {
      let big = [];
      mida.map((f) => {
        let items = [];
        var docRef = firestore
          .collection("Dish")
          .where("category", "==", "Lemon");
        docRef.get().then(function (querySnapshot) {
          querySnapshot.forEach(function (doc) {
            items.push({
              dish: doc.data().dish,
            });
          });
        });

        big.push({
          id: f.id,
          category: f.category,
          items,
        });
      });

      Setdata(big);

      Setload(false);
    }
  });
}, [mid]);

Category and Id are well. But the problem arises when I try to access items. So far I have tried to access it by index:

data[0].items[0]

But it just shows undefined in console.

When trying to use map on the data[0].items . It just doesn't do anything, no errors, it just won't print any details.

Your problem is here:

  mida.map((f) => {
        let items = [];
        var docRef = firestore
          .collection("Dish")
          .where("category", "==", "Lemon");
        docRef.get().then(function (querySnapshot) {
          querySnapshot.forEach(function (doc) {
            items.push({
              dish: doc.data().dish,
            });
          });
        });

        big.push({
          id: f.id,
          category: f.category,
          items,
        });

Array.map runs synchronously, so you are running quickly through all the items in mida and kicking off the docRef.get() Promises as you go. However, the call to .map will run to the end before any of the Promises have completed, so when you try to push items in to big as the loop is running, the calls to get haven't returned and so items doesn't yet contain anything.

You could fix this by mapping your Promises in to an array and then using Promise.all to wait for them to complete, then calling Setdata with the result.

Something like this (untested):

 if (mid === false) {
      let big = []
      Promise.all(
        mida.map(f => {
          let items = []
          var docRef = firestore
            .collection('Dish')
            .where('category', '==', 'Lemon')
          return docRef.get().then(function(querySnapshot) {
            querySnapshot.forEach(function(doc) {
              items.push({
                dish: doc.data().dish,
              })
            })
            return { id: f.id, category: f.category, items }
          })
        }),
      ).then(results => {
        Setdata(results)
        Setload(false)
      })
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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