Express - Update
#
Lesson Objectives- Create an edit route
- Create a link to the edit route
- Create an update route
- Make the edit page send a PUT request
#
Edit# | Action | URL | HTTP Verb | EJS view filename |
---|---|---|---|---|
1 | Index | /fruits/ | GET | index.ejs |
2 | Show | /fruits/:index | GET | show.ejs |
3 | New | /fruits/new | GET | new.ejs |
4 | Create | /fruits/ | POST | none |
5 | Edit | /fruits/:id/edit | GET | edit.ejs |
6 | Update | /fruits/:id | PUT | none |
7 | Destroy | /fruits/:index | DELETE | none |
#
Update#
Create an update routeIn order to UPDATE, we use the http verb PUT.
Inside server.js add the following:
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 routeIn our server.js
, create a GET route which will just display an edit form for a single fruit
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
<!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>
#
Create a link to the edit routeInside our index.ejs
file, add a link to our edit route which passes in the index of that item in the url
<!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 requestWhen we click "Submit Changes" on our edit page (edit.ejs), the form needs to make a PUT request to our update route
<!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
<!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>