BURGERFLIPPER101
BURGERFLIPPER101

Reputation: 1342

FindOneandUpdate method removes all elements from array instead of just specified

I'm creating a post request from the client to the server '/removeuser'.

router.post('/removeuser', (req, res) => {
    let errors;
    const userId = req.body.userId;
    const roomId = req.body.roomId;

    Room.findOneAndUpdate({_id: roomId }, { $pull: { users: { id: userId } }}, {new: true})
    .then(doc => {
        console.log(doc)
        console.log("User removed." + userId)
        res.json({roomId});
    })
    .catch(err => {
        console.log(err + " some error happened")
        return res.status(404).json(errors);
    });

})

I have console logged the roomId and the userId, they're both present. It even returns success and sends the response. Yet I notice it doesn't function as expected because once a user leaves the room, I notice all users disappear. I checked the DB instance after a user leaves and the users subarray is empty.

Would anyone have any advice? Thank you.

Room Schema:

const RoomSchema = new Schema({
    owner: {
        id: {
            type: String
        },
        username: {
            type: String
        }
    },
    roomname: {
        type: String,
        required: true
    },
    category: {
        type: String,
        required: true
    },
    password: {
        type: String,
        required: false
    },
    users: [UserSchema],
    messages: [{
        username: {
            type: String
        },
        message: {
            type: String
        },
        time: {
            type: String
        }
    }],
    date: {
        type: Date,
        default: Date.now
    }
});

User Schema:

 const UserSchema = new Schema({
    username: {
        type: String,
        required: true
    },
    email: {
        type: String,
        required: true
    },
    password: {
        type: String,
        required: true
    },
    avatar: {
        type: String
    },
    date: {
        type: Date,
        default: Date.now
    }
});

Upvotes: 1

Views: 89

Answers (3)

BURGERFLIPPER101
BURGERFLIPPER101

Reputation: 1342

Thanks for all your responses.

Removing the item by ID was not working. I'm on a short time limit so I had to find a different solution. If anyone ever comes across this problem, what I did was use the whole user object itself and use it to reference the one in the database, which ended up working.

 Room.findOneAndUpdate({_id: roomId}, {"$pull" : {"users" : user}})
        .then(doc => {
            console.log("User removed.")
            res.json({roomId});
        })
        .catch(err => {
            console.log(err + " some error happened")
            return res.status(404).json(errors);
    });

Upvotes: 1

Moad Ennagi
Moad Ennagi

Reputation: 1073

You could use subdocuments' remove() method:

Room.findOne({_id: roomId })
.exec()
.then(doc => {
    doc.users.id(userId).remove();
    doc.save();
    console.log("User removed." + userId)
    res.json({roomId});
})
.catch(err => {
    console.log(err + " some error happened")
    return res.status(404).json(errors);
});

Upvotes: 0

Mohammad Zeeshan
Mohammad Zeeshan

Reputation: 905

Room.update({_id: roomId }, { $pull: { users: { $elemMatch: { id: userId  } } }}, { multi: false })

Use $elemMatch will solve your problem

Upvotes: 0

Related Questions