Search code examples
jqueryjquery-deferredgoogle-geocoder

Google Geocoder and jQuery Deferred


I was wondering, if there is a way to get jQuery Deferred working with Google Geocoder. I tried something like:

// ...

_geocoder: function( address ) {
    if ( !this.props.geocoder ) {
        this.props.geocoder = new google.maps.Geocoder();
    }

    var deferred = $.Deferred(),
        geocoder;           

    geocoder = this.props.geocoder.geocode( { 'address': address }, function( results, status ) {
        if ( status === google.maps.GeocoderStatus.OK ) {
            deferred.resolve({
                lat: results[ 0 ].geometry.location.k,
                lng: results[ 0 ].geometry.location.A
            });
        } else {
            deferred.reject();
        }

        return deferred.promise();
    });

    $.when( geocoder() ).then(
        function( data ) {
            alert( status );
        },
        function() {
            alert( "Defer rejected" );
        }
    );
},


// ...

However google.maps.Geocoder doesn't return a jQuery Deferred object, so this code won't work as expected. Is there any other way to do it? I'm not sure about return deferred.promise(); either, because I looked at some code examples, which just used return deferred;. Is there any difference?


Solution

  • I would do something like this :

    // ...
    _geocoder: function(address) {
        var geocoder = this.props.geocoder;
        if (!geocoder) {
            geocoder = this.props.geocoder = new google.maps.Geocoder();
        }
        return $.Deferred(function(dfrd) {
            geocoder.geocode({'address': address}, function(results, status) {
                if(status === google.maps.GeocoderStatus.OK) {
                    dfrd.resolve(results[0]);
                } else {
                    dfrd.reject(new Error(status));
                }
            });
        }).promise();
    },
    // ...
    

    Note: By resolving the Deferred with the entire results[0] object, more potentially usable data is made available down the promise chain. See API Reference

    Test as follows :

    yourNamespace._geocoder('some address').then(function(result) {
        console.dir(result.geometry.location);
    }, function(err) {
        console.error(err);
    });