I'm building an app where people are able to make potlucks and invite other users to their potlucks. I have what seems to be a simple problem but I haven't been able to make it work:
I want to make an invite route that checks the potluck.attendees to see if they have been invited before (and send different errors depending on if they're 0-pending, 1-attending or re-invite them if they have been invited before and their status is 2 declined) and if not, puts the invitee into the potluck.attendees object array and the potluck's _id into the invitee's user.potlucks object array.
Here are super-trimmed versions of those two models:
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'
}
}
]
});
And what I have so far on this route is:
router.put('/attendees/invite/:potluckId/:inviteeId', async (req, res) => {
try {
const currPotluck = await db.Potluck.findOne({
_id: req.params.potluckId,
createdBy: req.user._id
});
// Makes sure potluck belongs to user before allowing to invite
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++) {
// Checks if invitee already exists in potluck.attendees
// and if their status is 0 or 1 (pending or attending)
// It will stop function
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
) {
// if their status is 2 (declined)
// it will edit their existing object in the attendees array to pending
// and re-insert potluck in invitee's user.potlucks model
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!`);
}
}
// If they don't exist already in potluck.attendees, create new object
// in potlucks.attendees and user.potlucks for invitee
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 to the issue:
If I run this code in postman, it will run the two 'findOneAndUpdate's that come after the for-loop regardless if there is a match or not. When trying to debug, I console.logged both invitee._id
and currPotluck.attendees[i].attendeeId
(for a test where I knew the invitee already existed in the array) and they both come up as the same id.
But if I try to console.log (currPootluck.attendees[i].attendeeId == invitee._id)
it comes up false
every time. I did a 'type of' for both and they come up as objects, and they both appear to be the same type in console.logs - strings maybe?
I know the solution must be something super simple but I can't figure it out, any help would be much appreciated!