I am currently working on an application that allows users to organize potluck events and invite other users to participate. While it may seem like a straightforward task, I have encountered a problem that I can't seem to solve:
The issue I am facing involves creating an invite route that checks the attendees of a potluck to determine if they have already been invited before. Depending on their status (0-pending, 1-attending, or 2-declined), different error messages should be sent. If the user has not been invited yet, they should be added to the potluck's list of attendees and the potluck's ID should be added to the user's list of potlucks.
Here are simplified versions of the two models involved:
Simplified Potluck Model
const PotluckSchema = new Schema({
attendees: [
{
attendeeId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
status: Number,
enums: [
0, //'pending',
1, //'attending',
2 //'declined'
]
}
]
});
Simplified User Model
const UserSchema = new Schema({
potlucks: [
{
potluck: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Potluck'
}
}
]
});
Below is my progress on this route so far:
router.put('/attendees/invite/:potluckId/:inviteeId', async (req, res) => {
try {
const currPotluck = await db.Potluck.findOne({
_id: req.params.potluckId,
createdBy: req.user._id
});
// Ensures that the potluck belongs to the user before allowing invitations
if (!currPotluck)
return res.status(401).json({
msg: 'You are not authorized to invite people to this potluck.'
});
const invitee = await db.User.findOne({ _id: req.params.inviteeId });
console.log(currPotluck);
console.log(invitee);
for (let i = 0; i < currPotluck.attendees.length; i++) {
if (
currPotluck.attendees[i].attendeeId == invitee._id &&
currPotluck.attendees[i].status == 0 ||
currPotluck.attendees[i].attendeeId == invitee._id &&
currPotluck.attendees[i].status == 1
) {
return res.status(401).send({
error: 'This member has already been invited to your potluck'
});
} else if (
currPotluck.attendees[i].attendeeId == invitee._id &&
currPotluck.attendees[i].status == 2
) {
await db.Potluck.findOneAndUpdate(
{ _id: currPotluck._id },
{ $set: { 'attendees.$[el].status': 0 } },
{ arrayFilters: [{ 'el.attendeeId': invitee._id }] }
);
await db.User.findOneAndUpdate(
{ _id: invitee._id },
{ $push: { potlucks: { potluck: currPotluck._id } } }
);
res.send(`This user has been re-invited to your potluck!`);
}
}
await db.Potluck.findOneAndUpdate(
{ _id: currPotluck._id },
{ $push: { attendees: { attendeeId: invitee._id, status: 0 } } }
);
await db.User.findOneAndUpdate(
{ _id: invitee._id },
{ $push: { potlucks: { potluck: currPotluck._id } } }
);
res.send(`This user has been invited to your potluck!`);
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
});
Now onto the problem:
When testing this code in Postman, both the 'findOneAndUpdate' functions that follow the for-loop are executed regardless of whether there is a match or not. During debugging, I noticed that when comparing invitee._id
with
currPotluck.attendees[i].attendeeId
(knowing that the invitee already exists in the array), they appear to have the same IDs. However, when I try to compare them directly, it yields false
every time. Upon further inspection with console logs, both variables appear as objects but potentially of different types - perhaps strings?
Although I believe the solution might be simple, I am unable to identify it at the moment. Any assistance would be greatly appreciated!