Home > OS >  findByIdAndUpdate adding another document to the database rather than updating
findByIdAndUpdate adding another document to the database rather than updating

Time:01-03

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:

  1. the use of upsert: true is suspicious - I can't imagine when you'd want to upsert this, and
  2. the lack of $set is also unusual unless the patientObj 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.

  • Related