I’m working on friend requests for my Facebook clone. I have a button that sends a friend request to the user and the user gets a notification and either accepts or denies the request. Each request is handled inside a FriendRequest schema. What I’m trying to do is make it so when a user accepts a friend request, it maps all the accepted requests on screen to show a list of all friends.
Here is my FriendRequest schema
const friendRequestSchema = new mongoose.Schema({
sender: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true,
},
receiver: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true,
},
status: {
type: String,
enum: ["pending", "accepted", "rejected"],
default: "pending",
},
createdAt: {
type: Date,
default: Date.now,
},
});
Here is the GET request for friend requests. My issue is with the friends function
router.get("/requests", async (req, res) => {
const user = req.user;
const id = req.user.id;
const requests = await FriendRequest.find({
toUser: user._id,
status: "pending",
})
.populate("sender")
.populate("receiver");
const friends = await FriendRequest.find({
sender: req.user.id,
status: "accepted",
})
.then((listOfFriends) => {
console.log(`list of friends: ${listOfFriends}`);
})
.catch((e) => {
// handle error
res.status(500).send("Error accepting friend request");
});
res.render("requests", { requests, id, friends });
});
When I console.log my friends function I get this as a result.
list of friends: {
_id: new ObjectId("6471d4a3a705acadf8af8923"),
sender: new ObjectId("6454407483df47caef5004e2"),
receiver: new ObjectId("647194ab12f45b12964aed6a"),
status: 'accepted',
createdAt: 2023-05-27T10:00:03.259Z,
__v: 0
}
Which is exactly what I want. But when I put this code in my ejs page to map the usernames of all of this users friends:
<% friends.forEach(friend => { %>
<p><% friend.sender.username %></p>
<% }) %>
I get this error: Cannot read properties of undefined (reading 'forEach'). I’m guessing my code is right but the forEach is showing up as unidentified despite their being data there.
I’ve been messing around with this code for the past hour or so but can’t figure out what I’m doing wrong. All I’m trying to do is map the accepted friend requests on screen so the user can see who all of their friends are.
>Solution :
The issue you’re facing is likely due to the asynchronous nature of the await keyword.
The await keyword waits for the asynchronous operation to complete and returns the result, but it doesn’t transform the result into a promise itself.
Therefore, when you try to chain .then() after await, it won’t work as expected.
To fix the issue, you can simply assign the result of await FriendRequest.find(...) directly to the friends variable, like this:
const friends = await FriendRequest.find({
sender: req.user.id,
status: "accepted",
})
.populate("sender")
.populate("receiver")
.exec(); // Add .exec() to execute the query immediately
console.log(`list of friends: ${friends}`);
Then pass friends to ejs.