Updating data: Put, Patch and Delete HTTP Verbs
Tags: 100daysofcode, javascript, mongodb
Published: 2020-07-23 06:21:56

####Put
Put replaces a resource with another. It takes two parameters same as Post and Get verbs. We start by finding the resource by id using [mongoose `findById` method](https://dev.to/mtee/mongoose-find-2l5c).  
```javascript
studentRouter.route('/students/:studentId')
  .patch((req, res) => {
    //find resource by id
    Student.findById(req.params.studentId, (err, student) => {
      if (err) {
        return res.send(err);
      }
    });
  });
```
Next we access the existing properties and replace them with the incoming changes


```javascript
studentRouter.route('/students/:studentId')
  .put((req, res) => {
    //find resource by id
    Student.findById(req.params.studentId, (err, student) => {
      if (err) {
        return res.send(err);
      }

      //Access existing properties and Update resource properties
      student.firstName = req.body.firstName;
      student.lastName = req.body.lastName;
      student.major = req.body.major;
    });
  });

```

Lastly we save and return the data or an error.
```javascript
studentRouter.route('/students/:studentId')
  .put((req, res) => {
    //find resource by id
    Student.findById(req.params.studentId, (err, student) => {
      if (err) {
        return res.send(err);
      }
      //Update resource properties
      student.firstName = req.body.firstName;
      student.lastName = req.body.lastName;
      student.major = req.body.major;

      //save and return data or an error
      student.save( (err) => {
        if (err) {
          return res.send(err)
        }
        return res.json(student);
      });
      
    });
  });
```

Suppose we want to change some properties of a resource in place of replacing the entire resource, Patch would be the better alternative.

####Patch
With patch we can update one or more properties of a resource. We check if the property exists and replace it with the the incoming changes.
```javascript
studentRouter.route('/students/:studentId')
  .patch((req, res) => {
    Student.findById(req.params.studentId, (err, student) => {
      if (err) {
        return res.send(err);
      }
      //Update one property
      if (req.body.firstName) {
        student.firstName = req.body.firstName;
      }
    });
  });


```
In a case where we have to update multiple properties, this quickly becomes tedious and redundant. An alternative is to use `Object.entries( )` method to return an array of key, value pairs. We can then chain a `forEach( )` method to loop through the array and update existing properties.

```javascript
studentRouter.route('/students/:studentId')
  .patch((req, res) => {
    Student.findById(req.params.studentId, (err, student) => {
      if (err) {
        return res.send(err);
      }
      //Code to prevent us from updating the id
      if (req.body._id) {
        delete req.body._id;
      }

      //The alternative
      Object.entries(req.body).forEach((item) => {
        const key = item[0];
        const value = item[1];
        student[key] = value;
      })

      //save and return data or an error
      student.save((err) => {
        if (err) {
          return res.send(err)
        }
        return res.json(student);
      });

    });
  });
```
NB: A resource id is a unique identifier of the resource, we wouldn't want to change that. To prevent that we can delete any incoming updates to the Id. That's why we included following code.

```javascript
//Code to prevent us from updating the id
    if (req.body._id) {
      delete req.body._id;
    }
```
####Delete
Delete completely removes a resource.

```javascript
 studentRouter.route('/students/:studentId')
  .delete((req, res) => {
    //find resource by id
    Student.findById(req.params.studentId, (err, student) => {
      if (err) {
        return res.send(err);
      }

      student.remove((err) => {
        if (err) {
          return res.send(err);
        }
        return res.sendStatus(204);
      })
    });
  });
```
A key thing to note is that the findById redundant. Try creating [middleware]( https://dev.to/mtee/middleware-lhn) to handle that.


_It's a wrap for Day 7!_