Ricky
Ricky

Reputation: 2907

AngularJS - Cannot get $q.reject and to work

Take a look at my code sample:

I've stripped it down to (what I believe are) the bare essentials, and I'm setting getting an error deferred.reject is not a function

angular
    .module('myApp')
    .service('myService', MyService);

MyService.$inject = ['$http', '$q'];

function MyService($http, $q) {
    var self = this;

    self.getResult = getResult;

    function getResult(id) {
        var deferred = $q.defer();

        deferred = $http.get('my/api/method', { params: { id: id } })
            .then(getResultCompleted)
            .catch(getResultFailed);

        function getResultCompleted(response) {
            if (response.data.ID > 0) {
                deferred.resolve(response.data);
            } else {
                deferred.reject(response);
            }
        }

        function getResultFailed(response) {
            deferred.reject(response);
        }

        return deferred.promise;
    }
}

Note: I know I can get this to work by simply returning the result of the $http call, however for the purposes of understanding these promise objects, I want to see if I can get this working by declaring and returning deferred as shown above

Thanks!

Upvotes: 3

Views: 424

Answers (2)

Vadim
Vadim

Reputation: 8789

Since $http.get() returns promise and success callback supports chaining API, you can define new deferred object inside of a callback and return it from there:

angular
    .module('myApp')
    .service('myService', MyService);

MyService.$inject = ['$http', '$q'];

function MyService($http, $q) {
    var self = this;

    self.getResult = getResult;

    function getResultCompleted(response) { // Tip: Define callback outside of getResult in order to avoid creating new instance of it each time getResult is called
        var deferred = $q.defer();
        if (response.data.ID > 0) {
            deferred.resolve(response.data);
        } else {
            deferred.reject(response);
        }
        return deferred.promise;
    }

    function getResult(id) {
        return $http.get('my/api/method', { params: { id: id } })
            .then(getResultCompleted);
    }
}

Note, that there is no error callback any more (just because it is redundant in this case).

In case request failed, the original rejected promise from $http.get() will be returned, otherwise a brand new promise from success callback will be used for follow-up .then() calls.

Upvotes: 1

Pankaj Parkar
Pankaj Parkar

Reputation: 136164

You are creating custom promise and returning it from your method, but mean while dealing with it you are overriding deferred(custom promise object) with $http.get, which also returns promise which has .then & .catch methods(Which doesn't have resolve & reject method). Because of that assignment, you can't have access to .resolve and .reject from deferred object.

deferred = $http.get('my/api/method', { params: { id: id } })

should be only

$http.get('my/api/method', { params: { id: id } })

Upvotes: 3

Related Questions