JoeCo
JoeCo

Reputation: 23

Function to geocode returning undefined with nodejs request module

Basically I have this code. I want to save the result of the request in the callback to a variable I can then return to another part of my program.

var request = require('request');

var geocodeLoc = function(location)
{
    var result;
    var baseURL = 'https://maps.googleapis.com/maps/api/geocode/json?address=' + location;
    request(baseURL, function(e, r, b){
        if(!e && r.statusCode == 200){
            result = (JSON.parse(b).results[0].geometry.location);
            console.log(result);
        }
    });
    return result
}
console.log( geocodeLoc('Hoxton') );

the result of console.log(geocodeLoc('Hoxton')) is returning before console.log(result) is executed.

The really frustrating thing is that the result of console.log(result) is exactly what I want.

Here is the output of the program

undefined
{ lat: 51.535638, lng: -0.08934399999999999 }

All I want is for geocodeLoc to return result. I'm kind of unfamiliar with NodeJS any help is much appreciated

Upvotes: 0

Views: 865

Answers (1)

AndreiC
AndreiC

Reputation: 542

This happens because your function makes an async request which has a delay, in order not to block the whole thread, node is continuing the execution, that's why your result logs after the first console log.You can use promises. I recommend promise-simple or q.

The result will look like this:

    var request = require('request');
    var Promise = require('promise-simple');
    var geocodeLoc = function(location)
    {
        var result;
        var d = Promise.defer();
        var baseURL = 'https://maps.googleapis.com/maps/api/geocode/json?address=' + location;
    request(baseURL, function(e, r, b){
        if(!e && r.statusCode == 200){
            result = (JSON.parse(b).results[0].geometry.location);
            console.log(result);
            d.resolve(result);
        }else{
            d.reject(e);
        }
    });
    return d;
}
// use it like this:
geocodeLoc('Hoxton').then(function(result){
    console.log('here is your result',result);
});

or if you really do not want to use another module, you can achive the same result using a callback function:

    var request = require('request');
    var geocodeLoc = function(location, callback)
    {
        var result;
        var baseURL = 'https://maps.googleapis.com/maps/api/geocode/json?address=' + location;
    request(baseURL, function(e, r, b){
        if(!e && r.statusCode == 200){
            result = (JSON.parse(b).results[0].geometry.location);
            console.log(result);
            callback(null, result);
        }else{
            callback(e);
        }
    });
}
// use it like this:
geocodeLoc('Hoxton', function(err, result){
    console.log('here is your result',result);
});

For callback functions is recommended that you always return the error as first parameter.

Upvotes: 4

Related Questions