user2106764
user2106764

Reputation: 23

jQuery deferred works wrong with google geocode

first of all, I want to say sorry because i know so many similar questions to this. i've read many of them, but i couldn't get the answer );

I'm building a web app with google map.

i wanted to use a kind of 'wait' or 'sleep' function in javascript to wait for asynchronous geocode() function to finish,

but after googling a while, now i understand that javascript doesn't have any of them, and i should use jQuery deferred to do that.

(I'm using jQuery 1.8.3, and testing with google chrome browser)

so i wrote my code like this, but it doesn't work.

Location.prototype.geocode = function() {
    deferred = new $.Deferred();
    var latLng = this.latLng;
    var point = null;

    geocoder.geocode( {'latLng': latLng},
        function(results, status) {
            var point = null;
            if (status == google.maps.GeocoderStatus.OK) {
                if (results[0]) {
                    alert(results[0].formatted_address); // alert in callback
                    point = get_something_blah_blah_function() /* set return value here */
                    deferred.resolve();
                } else {
                    deferred.reject();
                    alert('Geocder Error: no result');
                }
            } else {
                deferred.reject();
                alert('Geocoder Error: ' + status);
            }
        }

    );

    alert(deferred.state()); // alert 1
    deferred.then(alert(point)); // alert 2
    alert(deferred.state()); // alert 3

    return point; /* return value is set in geocode callback function */
}

i expected i see alert messages in this order,

  1. 'pending' (alert 1) -> 2. an address of the point (alert in callback) -> 3. '[object Object]' (alert 2) -> 4. 'resolved' (alert 3) because my code will wait by deferred until it is resolved,

but what i saw is 1. 'pending' (alert 1) -> 2. 'null' (alert 2) -> 3. 'pending' (alert 3) -> an address (alert in callback)

why didn't it wait until resolved or rejected?

i've tried it with done() and always() instead of then(), but all failed.

this problem is blocking me for a week...

Thanks in advance!

Upvotes: 2

Views: 1280

Answers (1)

DrColossos
DrColossos

Reputation: 12998

It seems you are not completely aware of how to work with deferrds.

Take a look the the example from the doc for promises. With deferrds, you never return the actual value but use the deferrd to return it.

So instead of returning point, you need to return a deferred.promise(). Then you can use $.when() to execute the callback, when the deferrd either was successfull or failed. In order to access the success or failed values, you need to pass your desired parameter to the appripriate function. You resolve or reject the deferrd, now do it with the values deferred.resolve(point).

So can can do something like this for accessing the point (replace geocode() with whatever returns the promise())

$.when(geocode()).then(function(point){
  console.log(point);
}, function() {
  console.log("the deferred got rejected");
});

Upvotes: 2

Related Questions