Skip to main content

Express - Update

Lesson Objectives

  1. Create an edit route
  2. Create a link to the edit route
  3. Create an update route
  4. Make the edit page send a PUT request

Edit

#ActionURLHTTP VerbEJS view filename
1Index/fruits/GETindex.ejs
2Show/fruits/:indexGETshow.ejs
3New/fruits/newGETnew.ejs
4Create/fruits/POSTnone
5Edit/fruits/:id/editGETedit.ejs
6Update/fruits/:idPUTnone
7Destroy/fruits/:indexDELETEnone

Update

Create an update route

In order to UPDATE, we use the http verb PUT.

Inside server.js add the following:

server.js
app.put("/fruits/:index", (req, res) => {
// :index is the index of our fruits array that we want to change
if (req.body.readyToEat === "on") {
//if checked, req.body.readyToEat is set to 'on'
req.body.readyToEat = true;
} else {
//if not checked, req.body.readyToEat is undefined
req.body.readyToEat = false;
}
fruits[req.params.index] = req.body; //in our fruits array, find the index that is specified in the url (:index). Set that element to the value of req.body (the input data)
res.redirect("/fruits"); //redirect to the index page
});

Test with cURL

curl -X PUT -d name="tomato" -d color="red" localhost:3000/fruits/2
curl localhost:3000/fruits

Our last fruit (banana) should now be a tomato

Create an edit route

In our server.js, create a GET route which will just display an edit form for a single fruit

server.js
app.get("/fruits/:index/edit", (req, res) => {
res.render(
"edit.ejs", //render views/edit.ejs
{
//pass in an object that contains
fruit: fruits[req.params.index], //the fruit object
index: req.params.index, //... and its index in the array
}
);
});

Now let's grab our create form and update it for editing in views/edit.ejs

views/edit.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h1>Edit Fruit Page</h1>
<form action="/fruits" method="POST">
<label for="name">Name</label>
<input type="text" name="name" id="name" />
<label for="color">Color</label>
<input type="text" name="color" id="color" />
<label for="isReadyToEat">Is Ready to Eat</label>
<input type="checkbox" name="readyToEat" id="isReadyToEat" />
<input type="submit" value="Edit Fruit" />
</form>
</body>
</html>

Inside our index.ejs file, add a link to our edit route which passes in the index of that item in the url

views/index.ejs
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8" />
<title>Index of Fruits</title>
<link rel="stylesheet" href="main.css" />
</head>
<body>
<h1>Index of Fruits</h1>
<nav>
<a href="/fruits/new">Create a New Fruit</a>
</nav>
<ul>
<% fruits.forEach((fruit, index) => { %>
<li>
<a href="/fruits/<%=index%>"> <%= fruit.name %></a>
<form action="/fruits/<%= index %>?_method=DELETE" method="POST">
<input type="submit" value="DELETE" />
</form>
<a href="/fruits/<%=index %>/edit">Edit</a>
</li>
<% }) %>
</ul>
</body>
</html>

Make the edit page send a PUT request

When we click "Submit Changes" on our edit page (edit.ejs), the form needs to make a PUT request to our update route

views/edit.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Edit a Fruit</title>
</head>
<body>
<h1>Edit Fruit Page</h1>
<form action="/fruits/<%=index%>?_method=PUT" method="POST">
<label for="name">Name</label>
<input type="text" name="name" id="name" />
<label for="color">Color</label>
<input type="text" name="color" id="color" />
<label for="isReadyToEat">Is Ready to Eat</label>
<input type="checkbox" name="readyToEat" id="isReadyToEat" />
<input type="submit" value="Edit Fruit" />
</form>
</body>
</html>

What is frustrating, is that our users have to remember which fruit they clicked on and update/reenter all the values.

We should at least set values in the form for the user to update

views/edit.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Edit a Fruit</title>
</head>
<body>
<h1>Edit Fruit Page</h1>
<form action="/fruits/<%=index%>?_method=PUT" method="POST">
<label for="name">Name</label>
<input type="text" name="name" id="name" value="<%=fruit.name%>" />
<label for="color">Color</label>
<input type="text" name="color" id="color" value="<%=fruit.color%>" />
<label for="isReadyToEat">Is Ready to Eat</label>
<input type="checkbox" name="readyToEat" id="isReadyToEat"
<% if(fruit.readyToEat === true){ %>
checked
<% } %> />
<input type="submit" value="Edit Fruit" />
</form>
</body>
</html>