20

I'm trying to create a function that returns a object with information of a callback:

var geoloc;

var successful = function (position) {
    geoloc = {
        longitude: position.coords.longitude,
        latitude: position.coords.latitude
    };
};

var getLocation = function () {
    navigator.geolocation.getCurrentPosition(successful, function () {
        alert("fail");
    });

    return geoloc;
};

How can I do this? The function getLocation return null value before successful is executed.

Thanks!

2
  • You have too many } in getLocation. Commented Jul 31, 2012 at 19:21
  • 3
    You have too many l's and too few s's in successful... ;) Commented Dec 17, 2013 at 16:20

2 Answers 2

25

Callbacks are used because the function is asynchronous. The callback runs at some point in the future.

So, yes getLocation returns before the callback is triggered. That's how asynchronous methods work.

You cannot wait for the callback, that's not how it works. You can add a callback to getLocation, that runs once it's done.

var getLocation = function(callback){
    navigator.geolocation.getCurrentPosition(function(pos){
        succesfull(pos);
        typeof callback === 'function' && callback(geoloc);
    }, function(){
        alert("fail");
    });
};

Now instead of doing var x = getLocation() and expecting a return value, you call it like this:

getLocation(function(pos){
    console.log(pos.longitude, pos.latitude);
});
Sign up to request clarification or add additional context in comments.

2 Comments

It is very interesting! The example works great and is perfect for my project. Thanks for helping me learn javascript.
Stumbled upon this answer, I'm trying to stream location data using websockets and this was tripping me up. This is definitely a step in the right directions, is there anything else I should be mindful of, as I'm trying to do the above with either setTimeout or setInterval to send location data every X seconds. Is this an advisable approach?
20

I would recommend the approach in Rocket's answer. However, if you really wanted to, you could trigger the rest of your code when the getLocation finishes by using a jQuery deferred object. This will give you more fine-grained control than just using the callbacks provided by getCurrentPosition.

// create a new deferred object
var deferred = $.Deferred();

var success = function (position) {
    // resolve the deferred with your object as the data
    deferred.resolve({
        longitude: position.coords.longitude,
        latitude: position.coords.latitude
    });
};

var fail = function () {
    // reject the deferred with an error message
    deferred.reject('failed!');
};

var getLocation = function () {
    navigator.geolocation.getCurrentPosition(success, fail); 

    return deferred.promise(); // return a promise
};

// then you would use it like this:
getLocation().then(
    function (location) {
         // success, location is the object you passed to resolve
    }, 
    function (errorMessage) {
         // fail, errorMessage is the string you passed to reject
    }); 

2 Comments

I've never actually messed with Deferred, but this looks pretty neat. +1
@Rocket i just started messing with it yesterday so now i'm trying to get every question to look like a nail so i can use my new hammer :P

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.