0

I came to a weird situation where console.log shows that the array is empty. However, when I open it, I see 2 elements in it. This behaviour even doesn't render component because it thinks conversations is empty.

Here is the code snippet:

  useEffect(() => {
    if (headers.length > 0) {
      let fetchedConversations = [];
      headers.map((conversation) =>
        conversation.conversators.filter(async (conversator) => {
          if (conversator !== user._id) {
            let conv = await getUserById(conversator);
            fetchedConversations.push(conv);
          }
        })
      );
      setConversations((prevState) => fetchedConversations);
    }
  }, [headers]);

getUserById.js

export const getUserById = async (id) => {
  //console.log(id);
  try {
    const config = {
      headers: {
        "Context-Type": "application/json",
      },
      withCredentials: true,
      credentials: "include",
    };
    const response = await axios.get(`${USERS_PATH}/${id}`, config);
    return response.data;
  } catch (err) {
    let data = await err.response?.data;
    console.log(data);
  }
};

Finally, here is the snippet of code where it should render something on the screen. Note that when I click on p tag it shows (finally) that there is 2 elements inside. However, conversations.length > 0 doesn't seem to re-render this.

return (
    <>
      <p onClick={() => console.log(conversations)}>sdas</p>
      {conversations.length > 0 &&
        conversations.map((conversation, id) => (
          <UserContainer key={id}>
            <UserIcon></UserIcon>
            <UserInfo>
              <UserName>
                {conversation?.name} {conversation?.surname}
              </UserName>
              <LastMessage>
                <SenderInfo></SenderInfo>
              </LastMessage>
            </UserInfo>
          </UserContainer>
        ))}
    </>
  );
}

First two consoles shows "empty" array, but it's not when opened. The last one console is when I press p tag First two consoles shows "empty" array, but it's not when opened. The last one console is when I press p tag

Mantofka
  • 206
  • 1
  • 12

1 Answers1

0

The problem is here:

 headers.map((conversation) =>
    conversation.conversators.filter(async (conversator) => {
      if (conversator !== user._id) {
        let conv = await getUserById(conversator);
        fetchedConversations.push(conv);
      }
    })
  );

You are pushing after awaiting a promise, but let the code continue on.

Try this:

 await Promise.all(headers.map((conversation) =>
    Promise.all(conversation.conversators.filter(conversator=>conversator !== user._id)
      .map(async (conversator) => {
            let conv = await getUserById(conversator);
            fetchedConversations.push(conv);
    }));
  ));

Map returns the promises, then you use Promise.all to make them all into one promise and await it. There certainly is a better way to turn this out, but that should be enough to get you to understand what's happening.

Salketer
  • 14,263
  • 2
  • 30
  • 58