user3890141
user3890141

Reputation: 111

req.body value undefined for form field value set by javascript function

I am building a node.js,express.js and passport.js app. Once logged into the profile I ask the user to click a button “Get Location” to get the users location.

Profile.ejs

<form action="/testform" method="post" >
  <div class="form-group">
  <input type="text" class="form-control" id="latVal" placeholder="latitude">
  <input type="text" class="form-control" id="longVal" placeholder="longitude">
  </div>
  <button type = "submit" class="btn btn-warning btn-sm">Save</button>
</form>
<button type = "submit" class="btn btn-warning btn-sm" onclick="getLocation()">Get Location</button>

onclick the getLocation() function is called which is located in mapCall.js

function getLocation() 
 …
 //call to showLocation()
} 

function showLocation(position) {
    …
    document.getElementById("latVal").value = latitude; 
    document.getElementById("longVal").value = longitude; 
}

showLocation() sets the values in the form to the latitude (id="latVal") and longitude (id="longVal") returned from the API call. The values appear in the form field. From here I want to save these values to the users profile data in MongoDB which I try to achieve in routes.js by click of the “Save” button which triggers the function below

app.post('/testform', isLoggedIn, function(req, res) {
        user.findById(req.user.id, function(err,user) {
            if(!user) {
                req.flash('error', 'No accound found');
                return res.redirect('/profile');
            }
            user.location.latitude = req.body.latVal;
            user.location.longitude = req.body.longVal;

            user.save(function(err){
                res.redirect('/profile');
            });
        });
    });

When I console.log req.body.latVal and req.body.longVal the value for these variables is undefined. Nothing is saved in the db.

In server.js I have

var bodyParser = require('body-parser');
app.use(bodyParser());

Upon looking into proposed solutions to req.body returning undefined I tried

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

I didn’t think adding the two lines above would work because the value returned by the API is not in JSON format. This did not work. I checked the typeof for latitude and longitude and it is a number. I am not sure why req.body is not picking up the value.

My initial guess was that app.post tries to read the value before the API can return a value in which case req.body.latVal would read an empty field. I added the save button to test that theory which also proved wrong.

The closest thing I found to my issue is this which was never resolved.

Any guidance is highly appreciated or perhaps even a better way to accomplish this will be great. The reason I have the form fields populate is because I couldn't think of another way to send the values from the frontend to the backend for saving.

Upvotes: 1

Views: 1325

Answers (2)

Sehel Amri
Sehel Amri

Reputation: 1

You are correct in most parts ,You just have to replace ID with name.that is the only way nodejs will be able to locate to your input field

Upvotes: 0

Aritra Chakraborty
Aritra Chakraborty

Reputation: 12542

Add the name attribute to your inputs.

<input type="text" class="form-control" id="latVal" placeholder="latitude" name="latVal">
<input type="text" class="form-control" id="longVal" placeholder="longitude" name="longVal">

EDIT: (from the comment)

You can do an AJAX call to your server after the getLocation() call.

function getLocation() {
    ///you get the lat and long
    showLocation(position)
    saveLocation(latitude, longitude)
    .then(function(resp){
        //do something with resp
    })
}
function saveLocation(latitude, longitude) {
    //we have native fetch in newer browsers, so
        return fetch("/testform", {
            method: "POST",
            headers: {
                "Content-Type": "application/json; charset=utf-8", //if this doesn't work use the below one
                // "Content-Type": "application/x-www-form-urlencoded",
            },
            body: JSON.stringify({latitude,longitude}), // body data type must match "Content-Type" header
        })
        .then(response => response.json());
}

This is just an outline of what you can do. Extend this code to your needs.

Upvotes: 2

Related Questions