0

I'm having trouble copying the mapped return of a onSnapshot listener from firebase inside an array (But very IMPORTANT : I don't want to use the state syntax):

  useEffect(() => {
    let copyChats = [];
    const unsubscribe = db.collection('chats').onSnapshot(snapshot =>

        (
            console.log(snapshot.docs.map(doc => ({
                    id: doc.id,
                    data: doc.data()
                }
            )))
        )
    )

    return unsubscribe;
}, [])

This code returns correctly the content in the console:

Array [
  Object {
    "data": Object {
      "chatName": "presidentielle",
    },
    "id": "8DRKgDCW54Zt4yf1anoR",
  },
  Object {
    "data": Object {
      "chatName": "titi",
    },
    "id": "9MudmtUfi9nGiWMpwHGk",
  },
  Object {
    "data": Object {
      "chatName": "essais",
    },
    "id": "Hi5a8FpDaf7EwwwpmOXn",
  },
  Object {
    "data": Object {
      "chatName": "titi",
    },
    "id": "ZnX3jaRkrJN4oiNCC3un",
  },
  Object {
    "data": Object {
      "chatName": "essais",
    },
    "id": "dPruNs46X0jbhr0sL7xk",
  },
  Object {
    "data": Object {
      "chatName": "test chat",
    },
    "id": "vxs7RdSBER83TOCPHko1",
  },
]
Array [
  Object {
    "data": Object {
      "chatName": "presidentielle",
    },
    "id": "8DRKgDCW54Zt4yf1anoR",
  },
  Object {
    "data": Object {
      "chatName": "titi",
    },
    "id": "9MudmtUfi9nGiWMpwHGk",
  },
  Object {
    "data": Object {
      "chatName": "essais",
    },
    "id": "Hi5a8FpDaf7EwwwpmOXn",
  },
  Object {
    "data": Object {
      "chatName": "titi",
    },
    "id": "ZnX3jaRkrJN4oiNCC3un",
  },
  Object {
    "data": Object {
      "chatName": "essais",
    },
    "id": "dPruNs46X0jbhr0sL7xk",
  },
  Object {
    "data": Object {
      "chatName": "test chat",
    },
    "id": "vxs7RdSBER83TOCPHko1",
  },
]

But what I want to do is to copy this exact data model in an the array copyChats, and I can't do it. I've tried all kinds of spread and push syntax.

   useEffect(() => {
        let copyChats = [];
        const unsubscribe = db.collection('chats').onSnapshot(snapshot =>

            (
                copyChats = snapshot.docs.map(doc => ({
                        id: doc.id,
                        data: doc.data()
                    }
                ))
            )
        )
        console.log(copyChats);
        return unsubscribe;
    }, [])

The only thing I'm able to get is an empty array !like the code above which give me this return:

Array []

If you have any Idea. Thank you..

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

1 Answers1

0

The problem is not where you access the array, but when you access it. If you run the code in a debugger, or add a console.log("Hello") inside he call, you'll see that the console.log(copyChats) actually runs before copyChats = snapshot.docs.map ever executes. So that explains why the array is empty: it hasn't been populated yet.

I don't want to use the state syntax

React's state is precisely the mechanism to pass data that is asynchronously loaded to the UI. If you want to render the data from the database in the UI, using state is the correct approach.

Also see:

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Thank you. Just figured it out during the afternoon (for the asynchronicity). I had just in mind that the useState reloads the whole file at every change, so I wanted to avoid it. Never mind. – Tercé Nicolas Sep 16 '21 at 17:01