I am using MEAN stack for patient CRUD operations. The update does not seem to be working properly. It adds another document to the database with the updated info but with a null id and leaves the old document that is supposed to be updated as is. below is the code I wrote in the service for update patient
editPatient(id:string,patient: Patient){
const headers = { 'content-type': 'application/json'}
const body=patient;
console.log(body)
let url=environment.PATIENT_BASE_URL environment.PATIENT.UPDATE_PATIENT "?userId=" id;
return this.httpClient.put(url, body);
}
Those are the contents of the environment file
export const environment = {
production: false,
BASE_URL:'http://localhost:3000',
PATIENT_BASE_URL:'http://localhost:3000/patients/',
PATIENT:{
GET_ALL_PATIENTS: 'list',
GET_PATIENT: 'view',
UPDATE_PATIENT: 'update',
DELETE_PATIENT: 'delete',
SEARCH_PATIENT: 'search',
ADD_PATIENT: 'add',
}
};
This is the code in patients.js
router.put('/update', function(req, res, next) {
const userId = req.body.userId;
let firstnameVal = req.body.firstName;
let lastnameVal = req.body.lastName;
let usernameVal = req.body.username;
let emailVal = req.body.email;
let birthDateVal = req.body.birthDate;
let genderVal = req.body.gender;
let patientObj = {
firstName: firstnameVal,
lastName: lastnameVal,
username: usernameVal,
email: emailVal,
birthDate : birthDateVal,
gender: genderVal
};
// patientsModel.update({'gender':'female'}, )
patientsModel.findByIdAndUpdate(userId, patientObj,{upsert: true, new: true} ,function(err, patientResponse){
if(err){
res.send({status:500, message: 'Unable to update the patient'});
}
else{
res.send({status:200, message: 'User updated successfully' ,results: patientResponse});
}
});
});
CodePudding user response:
Because you used this option
upsert: true
If item with id not found it creates a new document
you can read the docs here
Using the upsert option, you can use findOneAndUpdate() as a find-and-upsert operation. An upsert behaves like a normal findOneAndUpdate() if it finds a document that matches filter. But, if no document matches filter, MongoDB will insert one by combining filter and update as shown below.
CodePudding user response:
The second argument to findByIdAndUpdate is an update object. If it does not contain any update operators, it is treated as a replacement document.
If your intent is to replace the entire document so the only fields it contains are the ones provided in this function, add the _id
to the object:
let patientObj = {
_id: new mongoose.types.ObjectId(userId),
firstName: firstnameVal,
...
If the intent is to modify the provided fields but leave any others fields alone, use the $set update operator like
patientsModel.findByIdAndUpdate(userId, {"$set": patientObj}, ...
CodePudding user response:
There are a few problems with your code - as others have said:
- the use of
upsert: true
is suspicious - I can't imagine when you'd want to upsert this, and - the lack of
$set
is also unusual unless thepatientObj
represents the entire document you wish to set
both these items are causing you issues, but I suspect your main problem is actually that your ID doesn't match anything.
You mention an auto-generated ID. Mongo uses an ObjectId
(though mongoose perhaps does not) - depending on how you serialise this value, the string representation of it would probably look like this: 63b310df2b36d95e156a237d
- however when you query for that value (as you do with userId
) - it will return no matches, since you need to convert it to an object ID:
userId = new mongoose.types.ObjectId(req.body.userId)
You should also fix items 1 and 2 above.