2

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.

1
  • roland and Chandermani answered my question. As Chandermani's reply provides both approaches, it is accepted. Thanks all Commented Sep 22, 2013 at 9:52

2 Answers 2

3

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/

Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.