Matte
Matte

Reputation: 139

angular, promise and async function

today i have an issue that i really dont understand :)

I wrote an angular service that call my api, reformatting the result and bring this data to another function into angular controller. I do this so many times, but today something goes wrong.

The reformatting-result and the data accessed to the controller is not same and i dont know (maybe understand) why :D

This is the code of service:

myApp.factory('apiService', function($http) {
var myService = {
    getMunicipalityAsync : function(id) {
        var promise = null;
        promise = $http({
            method: 'GET',
            url: '/api2/cc/municipality/' + id
        }).success(function(response) {
            var r = {
                'success': true,
                'data': response.data
            };
            console.debug(r, 'return this');
            return r;
        }).error(function(data, status, headers, config) {
            logError("[apiService], getMunicipalityAsync() error, with status: " + status);
        });
        return promise;
    }
}
return myService;
});

And this is the code into the angular controller.

apiService.getMunicipalityAsync($scope.conf.geoarea).then(
    function( d ) {
        console.debug( d, 'return from service');
    }, function( error ) {
        alert('error');
    });

The debug datas is not the same :( look

Thanks!

Upvotes: 1

Views: 2515

Answers (1)

DanEEStar
DanEEStar

Reputation: 6270

The two methods success and error are specific methods of $http as explained in the docs in: http://docs.angularjs.org/api/ng.$http

These methods success and error get 4 parameters: data, status, headers and config. But the normal promise methods only get an object as a result. In your code you can actually see that parameter "d" you get in the then-function of getMunicipalityAsync contains the attributes data, status, headers and config. This is also explicitly mentioned in the docs:

"Since the returned value of calling the $http function is a promise, you can also use the then method to register callbacks, and these callbacks will receive a single argument – an object representing the response. See the API signature and type info below for more details."

apiService.getMunicipalityAsync($scope.conf.geoarea).then(
    function( d ) {
        console.debug( d.data, 'return from service');
    }, function( error ) {
        alert('error');
    });

But I think you have a misconseption. If you want to access the enhanced data in your controller then you have to create a new promise which you need to "resolve" with your enhanced data in the success method:

myApp.factory('apiService', function($http, $q) {
var myService = {
    getMunicipalityAsync : function() {
        var deferred = $q.defer();

        $http({
            method: 'GET',
            url: 'http://192.168.1.151/temp/angulartest/data/data.json'
        }).success(function(response) {
            var result = {
                'success': true,
                'data': response.data
            };
            console.debug(result, 'return this');
            deferred.resolve(result);
        }).error(function(data, status, headers, config) {
            logError("[apiService], getMunicipalityAsync() error, with status: " + status);
            deferred.reject();
        });
        return deferred.promise;
    }
}
return myService;
});

Then you can actually access the enhanced data directly in your controller:

apiService.getMunicipalityAsync().then(
    function(enhancedData) {
        console.debug(enhancedData, 'return from service');
    }, function(error) {
        alert('error');
    });

Upvotes: 3

Related Questions