-1

Hi I have exported using data (hawkers collection) using getDocs() from Firebase.

After that I put each hawker data as an object in an array called allStall as shown in the screenshot of the console log below.

enter image description here

Question 1 - How do I access each individual object in my allStall array. I try to use .map() to access each of it, but i am getting nothing.

Do note that I already have data inside my allStall array, see screenshot above. [Update] map doesn't work in code below because field is stallname not stallName. However, it needs to be async + await if using/call in/from other function.

Question 2 - Why is there [[Prototype]]: Array(0) in my allStall array

export /*Soln add async*/function getAllStall(){
  var allStall = [];
  try
  {
    /*Soln add await */getDocs(collection(db, "hawkers")).then((querySnapshot) =>
      {
        querySnapshot.forEach((doc) =>
          {
            var stall = doc.data();
            var name = stall.stallname;
            var category = stall.category;
            var description = stall.description;

            var stallData = {
              stallName:name,
              stallCategory:category,
              stallDescription:description
            };
            allStall.push(stallData);
});});

     console.log(allStall);

    //Unable to access individual object in Array of objects
    allStall.map(stall =>{console.log(stall.stallName);});}

  catch (e) {console.error("Error get all document: ", e);}

  return allStall;
}

In my main js file, i did the following:

useEffect(/*Soln add await*/() =>
    {
        getAllStall();
        /*Soln:replace the statement above with the code below
        const allStall = await getAllStall();
        allStall.map((stall)=>console.log(stall.stallname));
       */
    }
);
8

2 Answers 2

2

You are getting nothing because allStall is empty since you are not waiting for the promise to be fullfilled

try this

export const getAllStall = () => getDocs(collection(db, "hawkers"))
       .then((querySnapshot) =>
           querySnapshot.map((doc) =>
              {
                const {stallName, category, description} =  doc.data();
            
            return  {
              stallName:name,
              stallCategory:category,
              stallDescription:description
            };
           
          });
      )

try to change use effect like this

useEffect(async () =>
    {
        const allStats = await getAllStall();
        console.log(allStats)
        allStats.forEach(console.log)
    }
);
Sign up to request clarification or add additional context in comments.

12 Comments

@Liam You're right in principle but in this is case I used this mixed approach to avoid to change the code too much.
@lonelearner that console.log that you are referring to is the one in the code or one that you log by your own in the browser?
@lonelearner it is an async issue.
@lonelearner try my latest edit and see if it works
@lonelearner it's a const holding an arrow function. I changed it so in this way so I can avoid to use return and curly braces. It return a Promise of an array of object since it is an async request
|
0

A very big thanks to R4ncid, you have been an inspiration! And thank you all who commented below!

I managed to get it done with async and await. Latest update, I figure out what's wrong with my previous code too. I commented the solution in my question, which is adding the async to the function and await to getDocs.

Also map doesn't work in code above because field is stallname not stallName. However, it needs to be async + await if using in/calling from other function.

Helper function

export async function getAllStall(){

  const querySnapshot = await getDocs(collection(db, "hawkers"));

  var allStall = [];

  querySnapshot.forEach(doc =>
    {
      var stall = doc.data();
      var name = stall.stallname;
      var category = stall.category;
      var description = stall.description;

      var stallData = {
        stallName:name,
        stallCategory:category,
        stallDescription:description
      };

      allStall.push(stall);
   }
  );

  
  return allStall;
}

Main JS file

useEffect(async () =>
        {
            const allStall = await getAllStall();
            allStall.map((stall)=>console.log(stall.stallname));
        }
    );

Hurray enter image description here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.