I'm making a chat app and I'm trying to create dynamic chat pages based on room page names within firestore. My chat component updates the chatbox title depending on what it finds off of firestore. I have determined that the query I'm using does in fact pull the data correctly through console.log.
function Chat() {
const { roomId } = useParams();
const [roomDetails, setRoomDetails] = useState();
useEffect(() => {
const roomQuery = query(
collection(db, "rooms"),
where("name", "==", roomId)
);
if (roomId) {
const unsubscribe = onSnapshot(roomQuery, (snapshot) => {
setRoomDetails(snapshot.docs.map((doc) => ({ ...doc.data() })));
});
return () => {
unsubscribe();
};
}
}, [roomId]);
console.log(roomDetails);
return (
<div className="chat">
<div className="chat__header">
<div className="chat__headerLeft">
<h4 className="chat__channelName">
<strong>#{roomDetails?.name}</strong>
<StarBorderOutlinedIcon />
</h4>
</div>
<div className="chat__headerRight">
<p>
<InfoOutlinedIcon /> Details
</p>
</div>
</div>
</div>
);
}
What doesn't work is the bottom section
<h4 className="chat__channelName">
<strong>#{roomDetails?.name}</strong>
<StarBorderOutlinedIcon />
</h4>
Within my browser the chat title will be blank and I presume that it's because it isn't reading the data or the data isn't defined yet. Here is what the useState looks like in console.
console.log output
[{…}]0:
{name: 'general'}
length: 1
[[Prototype]]: Array(0)
Here's what Firestore looks like
CodePudding user response:
This will turn your state roomDetails
into an array:
setRoomDetails(snapshot.docs.map((doc) => ({ ...doc.data() })));
And array doesn't have property name
in it, so roomDetails?.name
returns undefined. You need to access like this:
<strong>#{roomDetails?[0].name}</strong>
This should give you the UI output.
CodePudding user response:
I found the solution I changed the way the Data was queried
useEffect(() => {
const roomQuery = query(
collection(db, "rooms"),
where("name", "==", roomId)
);
if (roomId) {
const unsubscribe = onSnapshot(roomQuery, (snapshot) => {
setRoomDetails(snapshot.docs.at(0).data());
});
return () => {
unsubscribe();
};
}
}, [roomId]);
The way the data is rendered is the same. Hope this helps some future people.