Why is request.body undefined?

I have a node-js server which includes bodyparser and everything:

var express = require('express');
var dbcon = require('./app/db/databaseconnection');
var bodyParser = require('body-parser');

var app = express();
var router = express.Router();

var filepath = __dirname + '/views/';
app.set('view engine', 'ejs');
app.use(express.static(__dirname + '/public'));
app.use('/', router);
app.use(bodyParser);
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: false })); // support encoded bodies
app.use('*', (request, response) => response.render(filepath + '404', { page_name: '404' }));


// var results = dbcon.getProducts().then(results => {
//      return results;
//  }).catch(err => { console.log(err) })
 //ejs.render(store , { results });
router.get('/', (request, response) => response.render(filepath + 'index', { page_name: 'home' }));
router.get('/store', (request, response) => {
    return dbcon.getProducts().then(results => {
        return response.render(filepath + 'store', { page_name: 'store', products: results });
    });
});
router.get('/product', (request, response) => {
    return dbcon.getProductDetails().then(results => {
        return response.render(filepath + 'product', { page_name: 'product', products: results, req: request });
    });
});
router.get('/purchase', (request, response) => {
    return dbcon.getProductDetails().then(results => {
        response.render(filepath + 'purchase', { page_name: 'purchase', products: results, req: request, res: response });
    });
});
router.post('/purchase', (request, response) => {
    //return dbcon.createCustomer(request.body.fname, request.body.lname, request.body.address, request.body.city, request.body.state, request.body.country, request.body.zip, request.body.phone, request.body.cardnumber, request.body.cardtype, request.body.expirationdate, request.body.securitycode, request.body.cardaddress, request.body.productID);
    console.log(request.body.name);
    response.redirect('/receipt');
});
router.get('/receipt', (request, response) => response.render(filepath + 'receipt', { page_name: 'receipt' }));
router.get('/about', (request, response) => response.render(filepath + 'about', { page_name: 'about' }));
router.get('/contact', (request, response) => response.render(filepath + 'contact', { page_name: 'contact' }));
router.get('/build', (request, response) => response.render(filepath + 'build/build'));
router.get('/learn', (request, response) => response.render(filepath + 'learn/learn'));

app.listen(3000, () => console.log("Server running at Port 3000"));

I also have a ejs page which includes a form:

<!DOCTYPE html>
<html>

<head>
    <title>PC Store | Purchase</title>
    <% include partials/header %>
    <link rel="stylesheet" link="/css/purchaseCanvas.css" />
    <script src="/js/toggleCountries.js"></script>
</head>

<body>
    <header>
        <% include partials/navbar %>
    </header>
    <main>
    <div class="container">
        <h1 align="center">Order</h1>
        <div class="orderproduct center">
        <% for (var i = 0; i < products.length; i++) { 
            //console.log(products[i]); 
            if (products[i].model == req.query.product) { %>
            <h4>Product: </h4>
            <img src="/img/productImages/<%= products[i].image01 %>" width="100">
            <h5>Brand: <%= products[i].brand %></h5>
            <h5>Model: <%= products[i].model %></h5>
            <h5>Series: <%= products[i].series %></h5>
            <h5>Price: $<%= products[i].price %></h5>
            <input type="hidden" id="productID" name="productID" value="<%= products[i].productID %>">
            <hr>
        <% }} %>
        </div>
        <form action="/purchase" method="post">
            <div class="canvas">
                <br><br>
                <div class="center">
                    <input type="text" class="form-control" id="fname" name="fname" placeholder="First Name" required>
                    <p id="fnameError" class="errorText"></p>
                </div><br>
                <div class="center">
                    <input type="text" class="form-control" id="lname" name="lname" placeholder="Last Name" required>
                    <p id="lnameError" class="errorText"></p>
                </div><br>
                <div class="center">
                    <input type="text" class="form-control" id="address" name="address" placeholder="Shipping Address" required>
                    <p id="addressError" class="errorText"></p>
                </div><br>
                <div class="center">
                    <input type="text" class="form-control" id="city" name="city" placeholder="City" required>
                    <p id="cityError" class="errorText"></p>
                </div><br>
                <div class="center">
                    <select class="form-control" id="country" name="country"></select>
                    <p id="countryError" class="errorText"></p>
                </div><br>
                <div class="center">
                    <select class="form-control" id ="state" name="state">
                        <option value="-1">Select State</option>
                    </select>
                    <p id="stateError" class="errorText"></p>
                </div> <br>
                <script>populateCountries("country", "state");</script>
                <div class="center">
                    <input type="text" class="form-control" id="zip" name="zip" placeholder="Zip Code" required>
                    <p id="zipError" class="errorText"></p>
                </div><br>
                <div class="center">
                    <input type="tel" class="form-control" id="phone" name="phone" placeholder="Phone Number" required>
                    <p id="phoneError" class="errorText"></p>
                </div><br>
                <div class="center">
                    <input type="text" class="form-control" id="cardnumber" name="cardnumber" placeholder="Card Number" required>
                    <p id="cardnumberError" class="errorText"></p>
                </div><br>
                <div class="center">
                    <select class="form-control" id="cardtype" name="cardtype">
                        <option value="-1">Select Card Type</option>
                        <option value="Visa">Visa</option>
                        <option value="MasterCard">MasterCard</option>
                        <option value="American Express">American Express</option>
                        <option value="Discover">Discover</option>
                    </select>
                    <p id="cardtypeError" class="errorText"></p>
                </div> <br>
                <div class="center">
                    <input type="date" class="form-control" id="expirationdate" name="expirationdate" placeholder="Expiration Date" required>
                    <p id="expirationdateError" class="errorText"></p>
                </div><br>
                    <div class="center">
                    <input type="text" class="form-control" id="securitycode" name="securitycode" placeholder="Security Code" required>
                    <p id="securitycodeError" class="errorText"></p>
                </div><br>
                <div class="center">
                    <input type="text" class="form-control" id="cardaddress" name="cardaddress" placeholder="Billing Address" required>
                    <p id="cardaddressError" class="errorText"></p>
                </div><br>
                <div class="center">
                    <input type="submit" class="btn btn-primary" value="Order">
                </div>
            </div>
        </form>
    </div>
    </main>
    <footer>
        <% include partials/footer %>
    </footer>
</body>

</html>   

From a post I read that you can use request.body to get the values from the inputs in the form. So I tried to do that but it doesn’t work.
When I do request.body it says undefined and when I try to do request.body.fname it says error and that name doesn’t exist. Anyone know what the problem could be? People have stated that it was because of the order of app.use, but I’ve tried changing it and it still wouldn’t work. Please Help!

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

Looks like you are hooking up your routes before any parsing middleware, which would explain why you don’t get any body (usually if it’s hooked up correctly you would at least get an empty object).

app.use('/', router);
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: false })); // support encoded bodies

Needs to be

app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: false })); // support encoded bodies
app.use('/', router);

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply