smallDisgruntledDog
smallDisgruntledDog

Reputation: 57

Trouble with a PUT request not updating the entry using MongoDB, Node and Express

Using the MERN stack and cannot get the PUT request to, in this case, update the patient information.

Patient routes- patient.js

//@route   POST api/patients
//@desc    Create patient profile
//@access  Private, patient information
router.post('/', [ auth,
    check('firstName', 'First Name is required')
        .not()
        .isEmpty(),
    check('lastName', 'Last name is required')
        .not()
        .isEmpty(),
    check('medicalConditions', 'Medical Conditions are required')
        .not()
        .isEmpty()
    ], 
    async (req, res) => {
        const errors = validationResult(req);
        if(!errors.isEmpty()) {
            return res.status(400).json({ errors: errors.array() });
        }

        const {
            firstName,
            lastName,
            dateOfBirth,
            phoneNumber,
            email,
            medicalConditions
        } = req.body

        //Build patient object
        const patientFields = {}
        if(firstName) patientFields.firstName = firstName;
        if(lastName) patientFields.lastName = lastName;
        if(dateOfBirth) patientFields.dateOfBirth = dateOfBirth;
        if(phoneNumber) patientFields.phoneNumber = phoneNumber;
        if(email) patientFields.email = email;
        if(medicalConditions) {
            patientFields.medicalConditions = medicalConditions.split(',').map(medicalCondition => medicalCondition.trim());
        }

        try {
            patient = new Patient(patientFields);
            await patient.save();
            res.json(patient)
        } 
        catch (err) {
            console.error(err.message);
            res.status(500).send('Server Error in Create/Update Patient');
        }
    }
);

//@route   GET api/patients/:patient_id
//@desc    Get patient by ID
//@access  Private, patient information
router.get('/:patient_id', auth, async (req, res) => {
try {
    const patient = await Patient.findById(req.params.patient_id);

    if(!patient) {
        return res.status(400).json({ msg: "This patient does not exist." });
    }
    res.json(patient)
} 
catch (err) {
    console.error(err.message);
    if(err.kind == 'ObjectId') {
            return res.status(400).json({ msg: 'Patient not found' })
        }
    res.json(500).send({ msg: 'Server Error in get patient by user ID' })
    }
});

//@route   PUT api/patients/:patient_id
//@desc    Update patient information
//@access  Private, patient information
router.put('/:patient_id', async (req,res) => {
    try {
        let patient = await Patient.findById(req.params.patient_id); 

        if(patient) {
            patient = await Patient.findOneAndUpdate(req.params.patient_id, 
                { 
                    firstName: req.body.firstName,
                    lastName: req.body.lastName,
                    dateOfBirth: req.body.dateOfBirth,
                    phoneNumber: req.body.phoneNumber,
                    email: req.body.email,
                    medicalConditions: req.body.medicalConditions 
                }
            );
        }
        return res.json(patient);
    } 
    catch (err) {
        console.error(err.message);
        res.status(500).send('Server Error in update patient info')
    }
});

I've been referencing a tutorial for this project but in the tutorial, the create profile route also updated the profile because it was referencing the id of the logged-in user.

When I test this with Postman I am sending in the patient_id in the url of the patient I want to update and it's sending back the information of a different patient in the db.

How do I modify the put request to update the patient information?

Thanks!

Upvotes: 0

Views: 124

Answers (2)

SuleymanSah
SuleymanSah

Reputation: 17858

mongoose findOneAndUpdate returns the original document, if you want to return the updated document you need to pass { new: true} in options.

https://mongoosejs.com/docs/api.html#model_Model.findOneAndUpdate

Also your query parameter must be like this: {_id:req.params.patient_id}

So your put route must be:

router.put("/:patient_id", async (req, res) => {
  try {
    let patient = await Patient.findById(req.params.patient_id);

    if (patient) {
      patient = await Patient.findOneAndUpdate(
        { _id: req.params.patient_id },
        {
          firstName: req.body.firstName,
          lastName: req.body.lastName,
          dateOfBirth: req.body.dateOfBirth,
          phoneNumber: req.body.phoneNumber,
          email: req.body.email,
          medicalConditions: req.body.medicalConditions
        },
        { new: true }
      );
    }
    return res.json(patient);
  } catch (err) {
    console.error(err.message);
    res.status(500).send("Server Error in update patient info");
  }
});

Another solution is to use findByIdAndUpdate which is shorter. Also it is a good practice to return 400-Bad request (or 404 not found) in case no doc found. (As you did in your get route)

router.put("/:patient_id", async (req, res) => {
  try {
    let patient = await Patient.findByIdAndUpdate(
      req.params.patient_id,
      {
        firstName: req.body.firstName,
        lastName: req.body.lastName,
        dateOfBirth: req.body.dateOfBirth,
        phoneNumber: req.body.phoneNumber,
        email: req.body.email,
        medicalConditions: req.body.medicalConditions
      },
      { new: true }
    );

    if (!patient) {
      return res.status(400).json({ msg: "This patient does not exist." });
    }

    return res.json(patient);
  } catch (err) {
    console.error(err.message);
    res.status(500).send("Server Error in update patient info");
  }
});

Upvotes: 2

Hobey823
Hobey823

Reputation: 272

You either never find the patient, or have errors updating. Try doing a .then & .catch on your update function and see any errors being thrown.

Upvotes: 0

Related Questions