How do I use jQuery promise/deffered in a custom function?

hitautodestruct picture hitautodestruct · Jan 17, 2013 · Viewed 25.8k times · Source

I have a function that gets the location through navigator.geolocation:

var getLocation = function( callback ){

    navigator.geolocation.getCurrentPosition( callback || function( position ){

        // Stuff with geolocation

    });

};

I would like to make it so that I could chain this function using jQuerys' Deffered object but I have still not managed to grasp the concept and usage of Deffered.

I'm looking for something similar to this Pseudo Code:

getLocation().then(function(){
    drawMarkerOnMap();
});

Is this syntax even possible without flipping over backwards and drowning in code?

Answer

Felix Kling picture Felix Kling · Jan 17, 2013

You have to instantiate a new deferred object and return it (or its promise) from the function. Call its .resolve method once you get the response:

var getLocation = function() {
    var deferred = new $.Deferred();

    navigator.geolocation.getCurrentPosition(function( position ){
        // Stuff with geolocation
        deferred.resolve(position);
    });

    // return promise so that outside code cannot reject/resolve the deferred
    return deferred.promise();
};

Usage:

getLocation().then(drawMarkerOnMap);

Reference: jQuery.Deferred


Addendum:

I would advise against using both approaches, deferred objects and passing callbacks to the function, to keep the interface simple. But if you have to stay backwards compatible, you can simply register the passed callback at the deferred object:

var getLocation = function(callback) {
    var deferred = new $.Deferred();

    if ($.isFunction(callback)) {
        deferred.then(callback);
    }

    navigator.geolocation.getCurrentPosition(function( position ){
        // Stuff with geolocation
        deferred.resolve(position);
    });

    // return promise so that outside code cannot reject/resolve the deferred
    return deferred.promise();
};