Skip to main content

CRUD App with Mongoose - Delete and Update

Lesson Objectives

Deletion:

  1. Create a Delete Button
  2. Create a DELETE Route
  3. Have the Delete Button send a DELETE request to the server
  4. Make the DELETE Route Delete the Model from MongoDB

Edit/Update:

  1. Create a link to the edit route
  2. Create an edit route
  3. Create an PUT route
  4. Have the edit page send a PUT request
  5. Make the PUT Route Update the Model in MongoDB
  6. Make the PUT Route Redirect Back to the Index Page

Create a Delete Button

In your index.ejs file

views/index.ejs
<li>
The <a href="/fruits/<%=fruits[i].id; %>"><%=fruits[i].name; %></a> is <%=fruits[i].color; %>.
<% if(fruits[i].readyToEat === true){ %>
It is ready to eat
<% } else { %>
It is not ready to eat
<% } %>
<!-- ADD DELETE FORM HERE-->
<form>
<input type="submit" value="DELETE"/>
</form>
</li>

Create a Delete Route

server.js
app.delete("/fruits/:id", (req, res) => {
res.send("deleting...");
});

Have the Delete Button send a DELETE request to the server

When we click "DELETE" on our index page (index.ejs), the form needs to make a DELETE request to our DELETE route.

The problem is that forms can't make DELETE requests. Only POST and GET. We can fake this, though. First we need to install an npm package called method-override

npm install method-override

Now, in our server.js file, add:

server.js
// include the method-override package
const methodOverride = require("method-override");
//...
// after app has been defined
// use methodOverride. We'll be adding a query parameter to our delete form named _method
app.use(methodOverride("_method"));

Now go back and set up our delete form to send a DELETE request to the appropriate route

views.index.ejs
<form action="/fruits/<%=fruits[i].id; %>?_method=DELETE" method="POST"></form>

Make the Delete Route Delete the Model from MongoDB

Also, have it redirect back to the fruits index page when deletion is complete

server.js
app.delete("/fruits/:id", async (req, res) => {
try {
const removeFruit = await Fruit.findByIdAndRemove(req.params.id);
res.redirect("/fruits"); //redirect back to fruits index
} catch (error) {
res.send(error);
};
});

In your index.ejs file:

views/index.ejs
<a href="/fruits/<%=fruits[i].id; %>/edit">Edit</a>

Create an edit route/page

First the route:

server.js
app.get("/fruits/:id/edit", async (req, res) => {
try {
const foundFruit = await Fruit.findById(req.params.id);
res.render("edit.ejs", {
fruit: foundFruit, //pass in found fruit
});
} catch (error) {
res.send(error);
};
});

Now the EJS:

views/edit.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1>Edit Fruit Page</h1>
<form>
<!-- NOTE: the form is pre-populated with values for the server-->
Name: <input type="text" name="name" value="<%=fruit.name%>"/><br/>
Color: <input type="text" name="color" value="<%=fruit.color%>"/><br/>
Is Ready To Eat:
<input type="checkbox" name="readyToEat"
<% if(fruit.readyToEat === true){ %>
checked
<% } %>
/>
<br/>
<input type="submit" name="" value="Submit Changes"/>
</form>
</body>
</html>

Create an PUT route

server.js
app.put("/fruits/:id", (req, res) => {
if (req.body.readyToEat === "on") {
req.body.readyToEat = true;
} else {
req.body.readyToEat = false;
}
res.send(req.body);
});

Have the edit page send a PUT request

In the edit.ejs

views/edit.ejs
<form action="/fruits/<%=fruit.id%>?_method=PUT" method="POST">

Make the PUT Route Update the Model in MongoDB

server.js
app.put("/fruits/:id", async (req, res) => {
if (req.body.readyToEat === "on") {
req.body.readyToEat = true;
} else {
req.body.readyToEat = false;
}
try {
const updatedFruit = await Fruit.findByIdAndUpdate(
req.params.id,
req.body,
{ new: true });
res.send(updatedFruit);
} catch (error) {
res.send(error);
};
});

Make the PUT Route Redirect Back to the Index Page

server.js
try {
const updateFruit = await Fruit.findByIdAndUpdate(req.params.id, req.body);
res.redirect("/fruits");
} catch (error) {
res.send(error);
};