Chung
Chung

Reputation: 1073

creating an angular service with Google map API service call back function

I am trying to create an angular service which uses google map geocoder, however I found the callback from google was executed after the execution of service function.

controller

app.controller( 'AppCtrl',['geocoder',function AppCtrl (geocoder) {
   var result=geocoder.geocode('greek');
   console.log(result);
});

service

app.service('geocoder',function() {
            this.geocode=function(address) {
                    var geocoder = new google.maps.Geocoder();
                    geocoder.geocode( { 'address': address}, function(results, status) {
                            if (status == google.maps.GeocoderStatus.OK) {
                                    console.log(results);
                                    return results;
                            } else {
                                    return ('Geocode was not successful for the following reason: ' + status);
                            }
                    });
            };
    });

The problem is , the console.log(result) in the controller outputs undefined and the console.log(results) in the service get the results back from google after the call of the function. That is, the callback function didn't return the results in time.

Is there a way to overcome this problem? Thanks.

Upvotes: 2

Views: 3903

Answers (2)

roland
roland

Reputation: 7775

As Chandermani pointed out, you need to provide your method with a callback:

app.service('geocoder',function() {
            this.geocode=function(address, outerCallback) {
                    var geocoder = new google.maps.Geocoder();
                    geocoder.geocode( { 'address': address}, function(results, status) {
                            console.log(results);
                            if (status == google.maps.GeocoderStatus.OK) {
                                    outerCallback({success: true, err: null, results: results});
                            } else {
                                    outerCallback({success:false, err: new Error('Geocode was not successful for the following reason: ' + status), results: null});
                            }
                    });
            };
    });

In your controller:

app.controller( 'AppCtrl',['geocoder',function AppCtrl (geocoder) {
   var result=geocoder.geocode('greek', function(callbackResult) {
      console.log(callbackResult); //{success: true, err: undefined, results: {...} or {success:false, err: Error object, results: undefined}
   });

});

If this works, you are then in good situation to refactor out the code to use a promise.

Hope this helps,

R.

Upvotes: 1

Chandermani
Chandermani

Reputation: 42659

Callbacks are the ways to handle async nature of network\web calls. You need to change the implementation of geocode method to either

  • Take a callback function are call into it when the response is received.
  • Return a promise that can be handled in the calling function using the then function.

I found this blog post that details both method http://markdalgleish.com/2013/06/using-promises-in-angularjs-views/

Upvotes: 3

Related Questions