Search code examples
javascriptjsonnode.jsgoogle-geolocation

Creating a callback to return an array from a function


I am trying to learn Node.js

I am having trouble creating my own call back on a function. It seems like such a simple thing but I don't quite understand how to do it.

The function is passed an address (example: "1234 will ln, co") which uses google's geolocate json api to return the full address, latitude and longitude in an array.

Here is my code:

//require secure http module
var https = require("https");

//My google API key
var googleApiKey = "my_private_api_key";

//error function
function printError(error) {
    console.error(error.message);
}

function locate(address) {
//accept an address as an argument to geolocate

    //replace spaces in the address string with + charectors to make string browser compatiable
    address = address.split(' ').join('+');

    //var geolocate is the url to get our json object from google's geolocate api
    var geolocate = "https://maps.googleapis.com/maps/api/geocode/json?key=";
    geolocate += googleApiKey + "&address=" + address;

    var reqeust = https.get(geolocate, function (response){

        //create empty variable to store response stream
        var responsestream = "";

        response.on('data', function (chunk){
            responsestream += chunk;
        }); //end response on data

        response.on('end', function (){
            if (response.statusCode === 200){
                try {
                    var location = JSON.parse(responsestream);
                    var fullLocation = {
                        "address" : location.results[0].formatted_address,
                        "cord" : location.results[0].geometry.location.lat + "," + location.results[0].geometry.location.lng
                    };
                    return fullLocation;
                } catch(error) {
                    printError(error);
                }
            } else {
                printError({ message: "There was an error with Google's Geolocate. Please contact system administrator"});
            }
        }); //end response on end

    }); //end https get request

} //end locate function

So when I try to execute my function

var testing = locate("7678 old spec rd");
console.dir(testing);

The console logs undefined because its not waiting for the return from locate (or at least I am guessing this is the problem).

How do i create a call back so when the locate function returns my array, it runs the console.dir on the array it returned.

Thanks! I hope my question makes sense, im self taught so my tech jargon is horrible.


Solution

  • You need to pass in the callback function to your method - so the callback might look something like this

    function logResult(fullLocation){
        console.log(fullLocation)
    }
    

    You would pass this in to your locate method along with the input:

    // note: no parentheses, you're passing a reference to the method itself, 
    // not executing the method
    locate("1234 will ln, co",logResult) 
    

    You can also do this inline - much like the response object you're already dealing with:

    locate("1234 will ln, co",function(fullLocation){
        // do something useful here
    }) 
    

    Now for the bit inside your method, instead of trying to return the result you just call the callback with the result:

    function locate(address, callback) {
        ......
    
        response.on('end', function (){
            if (response.statusCode === 200){
                try {
                    var location = JSON.parse(responsestream);
                    var fullLocation = {
                        "address" : location.results[0].formatted_address,
                        "cord" : location.results[0].geometry.location.lat + "," + location.results[0].geometry.location.lng
                    };
                    callback(fullLocation); // <-- here!!!
                } catch(error) {
                    printError(error);
                }
            } else {
                printError({ message: "There was an error with Google's Geolocate. Please contact system administrator"});
            }
        }); //end response on end
    
        .....
    }