0
const Home = () => {

const postsCollectionRef = collection(db, "data");
const [postList, setPostList] = useState([]);

useEffect(() => {
    const getPosts = async () => {
        const snapshot = await getDocs(postsCollectionRef);
        const data = snapshot.docs.map((doc) => ({ id: doc.id, ...doc.data() }))
        setPostList(data);
    };
    getPosts();
}, []);


    return (
    postList.forEach(post => {
        const example = post.data.Example;
        console.log(example);
        example.map((item) => {
            return <ExampleBlock
                A={item.A}
                B={item.B}
            />
        })
    })
    );
};

I was unable to consume the data i fetched from firestore. Attached with my data structure.

First, from the console log

console.log(postListArray);

it return the array successfully

Then, i tried to

console.log(postListArray.length);

it returned 0 (i believed it was 1, please point out my misunderstanding)

Then, i tried the code above

console.log(postListArray.data);

it returned undefined

Then, i tried to push my luck

console.log(postListArray.data.Example);

i believe it's type error

How can I access data inside the return object (if it had returned or not)?

data structure

some attempts on console log

type error?

updated console

2 Answers2

1

Since getPosts is an async function you need to use await or then when calling it. For example:

getPosts().then(() => {
  console.log(postListArray);
})

Without then() (or await) the console.log runs before the getPosts call completed, and thus before your array is populated.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
0

First, I see you're storing your list of posts as a const in your component, you should use some state to keep track of that, something along the lines of

const [postList, setPostList] = useState([]);

useEffect(() => {
  const getPosts = async () => {
    const data = await getDocs(postsCollectionRef);
    data.forEach((doc) => {
      const post = { ...doc.data() };
      setPostsList(prev => [...prev, post]);
    });
  getPosts();
});

Second, console.log(postListArray.data); won't work because postListArray is an array, and there is no data attribute on the Array type - You can take a look at the MDN documentation for the Array data type and it's attributes. Your postList will look like this:

postList: [
  {
    data: {...}
  },
  {
    data: {...}
  }
]

So you need to access each element in the array and get it's data attribute. Like this:

postList.forEach(post => {
  console.log(post.data) 
});

Then you can consume your list of posts by rendering it in your JSX if you map postList to an array of HTML elements like so:

return (
  <div>
    {
      postList.map((post, index) => <span key={index}>{post.data}</span>)
    }
  </div>
)
jon doe
  • 460
  • 1
  • 7
  • i don't know how to use useState and avoid the asynchronous issue described below https://stackoverflow.com/questions/72844183/pull-data-from-firestore-using-useeffect-works-on-re-render-only – Nooba Noobie Jul 03 '22 at 15:06
  • `useState` is one of the most if not the most basic and important hooks in react, I really think you should learn how to use it. @NoobaNoobie your component will not rerender if you don't store your post list in your component state – jon doe Jul 03 '22 at 15:09
  • I guess I got the whole picture now. I used to console.log within the closure of useEffect. I didn't know the asynchronous nature of this act. I saw empty object in console log and thought I was unsuccessful in returning data. I of course can grasp what useState meant to be. Now, I moved on. Your solution, I see and tried. But it didn't work out. Any idea? – Nooba Noobie Jul 05 '22 at 11:08
  • @NoobaNoobie what isn't working? p.s. I just noticed i had forgotten to call `getPosts` in my `useEffect`, so make sure that you did call it in your code – jon doe Jul 05 '22 at 11:18
  • I updated my code in after the return. This is where I could get the code to work if I import the same json file locally and expect proper functioning of components when i passed down too arrays A and B. The same code i used display errors as seen in the console and I am trying to figure it out. – Nooba Noobie Jul 06 '22 at 04:22
  • @NoobaNoobie Could you update the code in the question to the new code? It's hard to tell what's going wrong without looking at it – jon doe Jul 06 '22 at 04:55
  • yeah i did, please take a look – Nooba Noobie Jul 06 '22 at 04:58
  • The error message is pretty clear, somewhere in your code you are trying to call `item.map()` and `item` isn't an array so it doesn't have a `map` function. Look in your code a place where you are calling `item.map` – jon doe Jul 06 '22 at 05:17