user2921579 user2921579 - 3 years ago 181
Ajax Question

Javascript asynchronous function: callback not working

I am trying to return a result from an asynchronous function in Javascript.

I have seen this question: How do I return the response from an asynchronous call?, and I am trying to implement the callback solution, but something is wrong.

This is my code:

function getLocation(callback){
var lat;
var long;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position)
{
lat = position.coords.latitude;
long = position.coords.longitude;
}, function()
{
console.log('Please enable geolocation in your browser.');
});
} else {
alert('It seems like geolocation is not enabled in your browser.');
}
var res = {
"lat": lat,
"long": long
};
callback(res);
}

function getEventNearYou(){
var list = [];
getLocation(function(obj){
var lat = obj.lat;
var long = obj.long;
$.ajax({
url : 'http://www.skiddle.com/api/v1/events/search/?api_key=myapikey' + '&latitude=' + lat + '&longitude=' + long + '&radius=800&eventcode=LIVE&order=distance&description=1',
type : "GET",
async : false,
success : function(response) {
$(response).find("results").each(function() {
var el = $(this);
var obj = {
"eventname" : el.find("eventname").text(),
"imageurl" : el.find("imageurl").text(),
}
list.push(obj);
});
}
});
return list;
});
}


Basically, I want to find my current location, and create a HTTP get request to www.skiddle.com to retrieve events near that location.

This is how I call the function:

var x = getEventNearYou();


but I seem to have made a mistake, since I am getting the bad request error (
lat
and
long
are undefined).

Answer Source

You're using callbacks in a way that undermines their usefulness. You're still writing your code in a synchronous style. You should continue to reference: How do I return the response from an asynchronous call?

In the mean time, I'll restructure your code to show how it's done.

  1. As a rule of thumb, if any of the code inside a function uses callbacks, that outer function also needs to accept a callback as a parameter.

  2. If a variable is given a value inside a callback function, it won't be defined outside of the callback function (because asynchronous code always runs after synchronous code).

  3. Don't use async: false

function getLocation(callback){
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function (position) {
            var lat = position.coords.latitude;
            var long = position.coords.longitude;
            var res = { "lat": lat, "long": long }; 
            callback(res);
        }, function() {
            console.log('Please enable geolocation in your browser.');
        });
    } else {
        alert('It seems like geolocation is not enabled in your browser.');
    }
}

function getEventNearYou(callback) {
    getLocation(function(pos){
        var lat = pos.lat;
        var long = pos.long;
        $.ajax({
            url: 'http://www.skiddle.com/api/v1/events/search/?api_key=myapikey' + '&latitude=' + lat + '&longitude=' + long + '&radius=800&eventcode=LIVE&order=distance&description=1',
            type: "GET",
            success: function(response) {
                var list = [];
                $(response).find("results").each(function() {
                    var el = $(this);
                    var obj = {
                        "eventname": el.find("eventname").text(),
                        "imageurl" : el.find("imageurl").text(),
                    };
                    list.push(obj);
                });
                callback(list);
            } 
        });
    });
}

Then call getEventNearYou using a callback function:

getEventNearYou(function (events) {
    // code which relies on `events` can be called from here
});
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download