views:

69

answers:

2

I have a class object called Location that works with Google in order to geocode a given address. The geocode request is made trough an AJAX call and handled via a callback that will initiate the class members once the response arrives.

Here is the code:

function Location(address) {
    this.geo = new GClientGeocoder();
    this.address = address;
    this.coord = [];

    var geoCallback = function(result) {
        this.coord[0] = result.Placemark[0].Point.coordinates[1];
        this.coord[1] = result.Placemark[0].Point.coordinates[0];
        window.alert("I am in geoCallback() lat: " + this.coord[0] + "; lon: " + this.coord[1]);
    }

    this.geo.getLocations(this.address, bind(this, geoCallback));                   
}
Location.prototype.getAddress = function() { return this.address; }
Location.prototype.getLat = function() { return this.coord[0] }
Location.prototype.getLng = function() { return this.coord[1] }

My question is: it's possible to wait the response from Google before exiting the constructor?

I have no control over the AJAX request since it's made trough Google APIs.

I want to be sure that this.coord[] is properly initialized once a Location obj is created.

Thank you!

A: 

Is it possible to wait the response from Google before exiting the constructor?

I wouldn't recommend this approach. When you create a JavaScript object, you don't normally expect it to block for hundreds of milliseconds, until Google responds.

In addition, Google will throttle the GClientGeocoder if you attempt to do frequent requests (Source). There is also a cap for the number of requests a client can do in 24 hours. This would be complicated to handle systematically using this approach. You could easily get into a debugging nightmare if you will be having JavaScript objects that fail randomly.

Daniel Vassallo
+2  A: 

No, you can't (read: should not) wait. This is why it's called AJAX ("Asynchronous Javascript ...") in the first place. ;)

You could use a callback function yourself (untested code ahead).

function Location(address, readyCallback) {
  this.geo = new GClientGeocoder();
  this.address = address;
  this.coord = [];
  this.onready = readyCallback;

  this.geo.getLocations(this.address, bind(this, function(result) {
    this.coord[0] = result.Placemark[0].Point.coordinates[1];
    this.coord[1] = result.Placemark[0].Point.coordinates[0];
    if (typeof this.onready == "function") this.onready.apply(this);
  }));
}
Location.prototype.getAddress = function() { return this.address; }
Location.prototype.getLat = function() { return this.coord[0] }
Location.prototype.getLng = function() { return this.coord[1] }

// ... later ...

var l = new Location("Googleplex, Mountain View", function() {
  alert(this.getLat());
});
Tomalak