Get and Post
So far, we've only been rendering views, which is why we've been using GET for all of our routes. Now that we're working with data, we'll start to see how the other HTTP verbs come into play. Here we will focus on GET
and POST
.
Objectives
Implement
GET
andPOST
routes inexpress
.
1. Set up a new express app called crud_dinosaurs
.
crud_dinosaurs
.Incorporate express-ejs-layouts
.
Backend data store
We'll start workign with data from an actual database soon, but for now we'll just focus on routes and use, a JSON object as our data store. In the root of the project, create a dinosaurs.json
file with the following contents:
2. Index / Read (GET) route
Index is a route (URL) that lists all items of a specific type. It is a GET request to (in this example) /dinosaurs
.
Format the ejs to display the data. Assume that we will pass the data in as myDinos
.
Index view -- in /views/dinosaurs/index.ejs
To access our data, we'll use the fs
(filesystem) core module. Import this module in index.js
Now let's pull in our data and take a took at it.
Note: This console.log()
is in our server file, which means it will print to our terminal, NOT the browser inspector.
That doesn't look very helpful, does it? That's because we're pulling in a JSON object, which isn't quite the same as a normal JS object. JSON (JavaScript Object Notation), is a standard format for data that is being transmitted (sent back and forth), and it needs to be parsed, or converted to a true JS data type - in this case, an array. Read more about working with JSON here.
Try parsing the data before printing it:
That's more like it! Now lets send it to our EJS file:
In the above example we load the dinosaurs/index.ejs
view and pass it dinoData
as mydinosaurs
. Now we can access myDinos directly in the index.ejs
file.
3. Show / Read (GET) route
Show is a route that displays a single item of a specific type. Since we're still just reading data, it is a GET request to (in this example) /dinosaurs/1
Create a dinosaurs/show.ejs
file:
Now let's write our show route. We can access the index from the url through the req.params
object, but it will be a string. In order to use in to access an array value, we need to cast it to an integer.
Show route -- in index.js
In the above example we load the dinosaurs/show.ejs
view and pass it a specific item from the dinoData
array as myDino
. We use the :idx
url parameter to specify which animal to display. This means in the show.ejs
file we can access myDino directly.
4. New / Read (GET) route
To create an item (dinosaur in this example) we need to get the data about that item, so we'll use a form.
Form tags have two attributes that are very import for their CRUD functionality:
method: HTTP verb -
GET
orPOST
. You will use POST most often because it is significantly more secure. Read about the difference between these two methods by scrolling down to the "When to Use GET" AND "When to Use Post" sections of this page.action: This value should be a path. Specifically, it is the url pattern associated with the route that will handle the data - in this case, that will be the
/dinosaurs
POST route we will write.
Create a dinosaurs/new.ejs
view that contains an html form:
Now write a GET
route so we can view this form at localhost:3000/dinosaurs/new
:
Not working? Make sure this route is above the show (/dinosaurs/:idx
) route, otherwise the show route will catch the request and pass in "new" as req.params.idx
.
5. Create (POST) route
When the above form is submitted it will make a POST
to the url /dinosaurs
with the data contained in the form fields. To receive this data, we need to create the POST
route and use some middleware to make the data readable. This middleware is new to express
and prior to version 4, we had to manually install the body-parser
node package in order to use it. (If it bothers you that we're glazing over how the data comes through before we send it through something like body-parser
, read this article. It will always make sense to use some sort of framework like body-parser
in practice, but if you're interested in capturing the raw data, see this article.)
This middleware will store the data submitted from the form in a user-friendly req.body
object.
index.js
The express.urlencoded()
middleware tells body-parser to capture urlencoded data (form data) and store it in req.body
. The {extended: false}
option ensures that the values in this body will either be strings or arrays. More on this here. Further discussion on it here.
Now, if we can access the form data in a POST route!
index.js
Try adding a new dinosaur and make sure you see the appropriate data come through in the terminal when you submit the form.
body-parser Summary: Form data is passed as payload of the request. Every field that has a name will be included in that payload and it is sent as form encoded text. When body-parser
is used, it automatically parses the form body into a javascript object that we can use and it stores it in req.body
so we can use it (similar to how we convert API responses to JSON. All of this is done as middleware, which we just configured.
The name
attribute matters! In the above example we could access the dinosaur type form field by using req.body.type
and the name field by using req.body.name
. This correlates directly to the names given to the form fields in the form html above.
Generally, the code in the express route would contain code that would CREATE an item in a database and redirect the user to a route with a confirmation message of some sort or just back to the index route. For this example we're going to use the JSON file created above to store our data. This will involve three steps:
Reading the JSON file
Pushing the new animal to the object
Writing the new JSON file using fs.writeFileSync (this will replace the old dinosaurs.json)
JSON.stringify
does the opposite of JSON.parse
- it converts javascript data into json data.
Show / Read (GET) with a Form
There may be instances where you need to GET
dinosaurs, but you don't want them all. A good example is filtering dinosaurs with a specific name via a search bar.
In these cases, you don't want to use a POST action, because POST is reserved for creating new resources. Instead, we can create another form with a GET
method, and read the data via a querystring. This is an appropriate use of the GET
form method because the user input is not sensitive.
Add a form to dinosaurs/index.ejs
The idea here is that the search bar allows the user to filter what's on the page, so it will be a GET
request to /dinosaurs
... but we already have a route for that! When you submit a form using the GET
method, the key/value pairs are appended to the URL in a query string. Try searching for a dinosaur now and notice what happens to the URL. This query string, like parameters (req.params
) is available via the request object. We'll use a conditional to check if there's a querystring, then filter the dinosaurs if one is present.
Last updated