Intro
One of the major uses for the post request is with the sending of form data for processing. So to continue our discussion on the post req, we are going to set up a basic form with two inputs.
Order Tacos
Now this is a simple form but remember, we are processing the data with a post request, through a server, so we need to reflect this in our action and method properties of our form:
- <form action="http://localhost:3000/tacos" target="_blank" method="post">
notice the use of target="_blank" here. This was an experiment just to see if it would work, and guess what? It does. When you submit the form it opens the post results in a new page. Very Cool.
And next, we need to set up our server:
- Start by creating our working directory.
- Run npm init to create our package.json file.
- Run npm i express to install express.
- Create our "ServerFile" - index.js.
We're just going to run a basic server setup for this discussion, so our index.js file will look something like this:
- JavaScript
- const express = require('express');
- const app = express();
- const port = 3000;
-
- app.post( '/tacos', ( req, res ) => {
- res.send('post Tacos response');
- })
-
- app.listen( port, () => {
- console.log(`Server Online : Listening on port: ${ port }`);
- });
With that, our server is now set up. To start it, we open a "Terminal" window in our app's root express directory, and entering either node index.js, or nodemon index.js (if nodemon is installed.). And now if we submit the form, it will open a page and respond with:
confirming that our server is up and running, and that our form is posting.
Parsing the Data
So we now have our form built for the data input. And we have our basic server, set up and running, waiting for some data to process. This processing happens within the body of the req, which resides in our app.post call.
Let's add a console.log to our post req, to see the output of this req.body:
- app.post( '/tacos', ( req, res ) => {
- console.log(req.body);
- res.send('post Tacos response');
- })
and, what do we get....
Oh, we got undefined. Not what we expected. If we look at the express documentation for req.body, we see that it says:
- req.body contains key-value pairs of data, submitted in the request body. By default, it is undefined, and is populated when you use body-parsing middleware such as body-parser and multer.
so, without this middleware, we got exactly the response we were supposed to get. What this boils down to is that the data can be sent in many different formats, such as, text, html, json and many others. And each one of these different formats has to be parsed differently.
We can use some middleware that is built into express, by adding a line of code to our index.js server code. This goes near the top of the file, after our imports and variable declarations, like so:
- JavaScript
- ... Set the variables and requires ...
-
- app.use(express.urlencoded({ extended: true }))
-
- ... the rest of our server code ...
And now if we run this, submit our form, and check the console, we get:
- { meat: 'Beef', qty: '2' }
Our express middleware has identified the req.body as urlencoded data, allowing us to parse out the information. It's important to note that the output looks like a json file because "req.body Contains key-value pairs", but it isn't json data. It's urlencoded data with key/value pairs. We'll explain in a bit, (further down the page) why this distinction is important.
Ok, so far, so good, but our only output is to the console. We want to produce an output on a webpage, so let's restructure our app.post, like so:
- app.post( '/tacos', ( req, res ) => {
- const { meat, qty } = req.body;
- res.send(`Your Order is: ${qty} ${meat} tacos.`);
- })
We know that the req,body is going to return urlencoded data in key/value pairs, so we can use this info to extract our form input names and values for display in the res.send output. So once we submit our form, and check the output on our localhost /tacos page, we now see:
- Your Order is: 2 Beef tacos.
or whatever was input into the form.
So this is demonstrating how to parse our req.body, using urlencoded data which essentially takes the "string" values from our form inputs and converts them into key/value pairs.
We mentioned earlier in the page that we would discuss the distinction about our process being set up to only parse urlencoded data. This is what the express middleware that we used is doing when we defined express.urlencoded:
- app.use(express.urlencoded({ extended: true }))
The distinction here is that this express middleware is only designed to parse urlencoded form data that is coming from a form, and there are many other formats that can be used.
What if we were passing actual json data. This post request would return { unknown: unknown }, because this current express middleware can NOT parse json data, only urlencoded data.
Now we could easily solve the json problem by adding another app.use call to our server code:
- app.use(express.urlencoded({ extended: true }))
- app.use(express.json())
and now our app can parse urlencoded data AND json data. But the bigger point here is that the data can be sent in many different formats, and you'll need to use the proper "middleware" to parse which ever data format is being used.
And that my friends, is the basic concept of data parsing the req.body.
Final Code
Heres the final code for this discussion:
Input Form
- HTML
- // form input
- <form action="http://localhost:3000/tacos" target="_blank" method="post">
- <label for="meat">Type of Meat? </label>
- <select name="meat"></select>
- <option value="Beef" selected>Beef</option>
- <option value="Chicken">Chicken</option>
- <option value="Steak">Steak</option>
- <option value="Soft">Soft</option>
- </select>
- <label for="qty">How Many? </label>
- <input type="number" name="qty" min="1" value="1">
- <button>Submit</button>
- </form>
Server File
- JavaScript
- const express = require('express');
- const app = express();
- const port = 3000;
-
- app.use(express.urlencoded({ extended: true }))
- app.use(express.json())
-
- app.post( '/tacos', ( req, res ) => {
- const { meat, qty } = req.body;
- res.send(`Your Order is: ${ qty } ${ meat } Taco(s).`);
- })
-
- app.listen( port, () => {
- console.log(`Server Online : Listening on port: ${ port }`);
- });