Search code examples
javascriptangularjsangular-promiseangular-resource

Reject deferred in $update function of an angular $resource


In my angular application I update a task as follows

task.$update().then(function (task) {
   // success
}, function (response) {
   // failure
});

From the backend I get a 422 back, but the first callback is called.

My resource looks like this

angular.module('App')
    .factory('Task', function ($resource) {
        var resource = $resource('/admin/tasks/:id', { id: '@id' }, {
            new: {
                 method: 'GET',
                 url: '/admin/tasks/new'
            },
            update: {
                 method: 'PUT'
            },
            ...
        });

    return resource;
});

The question is, under which circumstances is the second callback called ? And if needed, what can I do in the update method such that the second callback is called?

UPDATE: The reason the success callback is called all the time is because of an error-interceptor I have

angular
.module('App')
    .factory('errorInterceptor', function ($location, $q, $rootScope) {
        return { 
            responseError: function (response) {
                if (response.config.url.match($location.$$host)) {
                    $rootScope.error = response;

                    return $q.reject(response);
                }

                return $q.when(response);
            } 
        };
    });

Apparently, if you do return $q.when(response); you tell angular that everything is fine, right ?


Solution

  • The callbacks are specified as params to the $update() functions, like this:

    $task.$update(function(task) {}, function(response) {})
    

    See official documentation of $resource :

    The action methods on the class object or instance object can be invoked with the following parameters:

    • HTTP GET "class" actions: Resource.action([parameters], [success], [error])
    • non-GET "class" actions: Resource.action([parameters], postData, [success], [error])
    • non-GET instance actions: instance.$action([parameters], [success], [error])

    The thing is that unlike $http, $update or any resource methods don't return a promise directly. They return an empty reference.

    Note that $resource uses $http internally, hence the $http docs apply (regarding callbacks) :

    A response status code between 200 and 299 is considered a success status and will result in the success callback being called. Note that if the response is a redirect, XMLHttpRequest will transparently follow it, meaning that the error callback will not be called for such responses.