Bootcamp
Search…
3.1.3: Handling POST Requests

Introduction

  1. 1.
    Our example form from 3.1.2: HTML Forms doesn't create data in our database yet because we haven't set up our server to handle the relevant requests.
  2. 2.
    We will create an Express route to listen for our POST requests and perform logic on the form data.

Receive POST Requests in Express

  1. 1.
    Express typically provides POST request data to us in the Express request object via the request.body attribute. To receive request body data in request.body we need to bind the following urlencoded middleware to Express above our routes. Read more about the urlencoded middleware in Express docs here.
    app.use(express.urlencoded({ extended: false }));
  2. 2.
    Inside the request.body object, keys will be the name attributes of the input form elements from the form that sent the request.
    <input type="text" id="label" name="label" value="chicken udon">
  3. 3.
    The following is an example route that receives POST requests to /recipe, logs the form data, and responds with a confirmation message.
    app.post('/recipe', (request, response) => {
    console.log('request body:', request.body);
    response.send('we saved your recipe');
    });

Store POST Request Data in JSON

Now that we can receive POST requests in Express, let's store the data from the requests in our JSON database data.json. We can also perform other logic on this data before and after storing it.

views/recipe.ejs

EJS template containing our POST request form.
<html>
<body>
<form action="/recipe" method="POST">
<label for="label">recipe label:</label><br />
<input type="text" id="label" name="label" /><br />
<label for="ingredients">ingredients:</label><br />
<input type="text" id="ingredients" name="ingredients" /><br />
<input type="submit" value="Submit" />
</form>
</body>
</html>

data.json

Sample JSON DB containing a single recipe so far.
{
"recipes": [
{
"label": "banana shake",
"ingredients": "bananas"
}
]
}

index.js

Express logic that handles incoming requests.
import express from 'express';
import { add } from './jsonFileStorage.js';
​
const app = express();
app.set('view engine', 'ejs');
​
// Configure Express to parse request body data into request.body
app.use(express.urlencoded({ extended: false }));
​
// Save new recipe data sent via POST request from our form
app.post('/recipe', (request, response) => {
​
// Add new recipe data in request.body to recipes array in data.json.
add('data.json', 'recipes', request.body, (err) => {
if (err) {
response.status(500).send('DB write error.');
return;
}
// Acknowledge recipe saved.
response.send('Saved recipe!');
});
});
​
// Render the form to input new recipes
app.get('/recipe', (request, response) => {
response.render('recipe');
});
​
app.listen(3004);
Note the following about our code in index.js.
  1. 1.
    We bind request-processing middleware like express.urlencoded to Express before our routes. This configures Express to process requests using that middleware before we handle those requests in our routes.
  2. 2.
    There are 2 routing methods with path /recipe, 1 for POST and 1 for GET requests. These routes don't interfere with each other; POST requests go to the post handler, and GET requests to the get handler.
  3. 3.
    Express methods like response.send and response.render terminate the current request-response cycle, meaning no other middleware will execute after these methods run. See all cycle-terminating response methods here.

Exercises

  1. 1.
    Execute the above code and verify it adds new recipes to our DB.
  2. 2.
    Change the name attribute in 1 of the form input elements, re-send the request, and observe the key change in request.body.