How to handle $resource service errors in AngularJS
Asked Answered
B

3

97

I am making requests to my API and I am using AngularJS $resource module. It's different from $http so I don't know how to handle my errors.

My service:

var appServices = angular.module('app.services', ['ngResource']);
appServices.factory('Category', ['$resource',
    function($resource){
        return $resource('/apicategoryerr/?format=:format', {}, {
            query: {
                method: 'GET', 
                params: { format: 'json'}, 
                isArray: true,

            }
        });
    }]);

My Controller:

...
Category.query(function(data) {
                console.log(data);
            });
...

I want something like this or .. I don't know a way to handle errors if my API is not working..

Category.query().success(function() {
                console.log('success');
            }).error(function() {
                console.log('error');
            });
Boutique answered 14/12, 2013 at 14:17 Comment(0)
S
181

you can pass the error handler as a second parameter toquery.

Category.query(function(data) {}, function() {});

EDIT:

to make things a bit clearer, some examples:

var Resource = $resource('/restapi/resource');

Resource.query(function(data) {
    // success handler
}, function(error) {
    // error handler
});

Resource.query({
    'query': 'thequery'
},function(data) {
    // success handler
}, function(error) {
    // error handler
});

Resource.query().$promise.then(function(data) {
    // success handler
}, function(error) {
    // error handler
});

Resource.query({
    'query': 'thequery'
}).$promise.then(function(data) {
    // success handler
}, function(error) {
    // error handler
});
Semi answered 14/12, 2013 at 14:23 Comment(8)
In the documentation it looks more like the 3rd parameter is the error callback. "Resource.action([parameters], [success], [error])" docs.angularjs.org/api/ngResource.$resourceRussellrusset
is there a way to define a default error handler common to all use of this resource (e.g. "resource not authorized by server" ?Languedoc
@NicolasJanel You could define a function that would handle it then do Resource.query().$promise.then(function(data) {}, errorFunction). You'll still have to include it every place you use a query, but at least you won't be redefining it each time.Huskey
@Boutique I'd appreciate it if you accept this as the answer for this questionSemi
Does the $promise method only work with query methods? Because if I try to use it on a create or delete method, I get a Cannot read property 'then' of undefined. At the same time the query method works like that.Liles
@Kaspar the return value of instance methods such as myResource.$save and myResource.$delete is the promise. So you can just do myResource.$save().then(...).Disembody
the third option worked for me. seemed the cleanest. fell in place with automatic api and documention in django-angular.Elo
For people googling this in the future, the first two shortcut methods do not work as of Angular 1.5.2.Hyperbole
L
69

You can define a error handler at the creation step of the resource by adding an interceptor object in the description of a method, with a responseError property, linked to your error function.

function resourceErrorHandler(response) { ... }

$resource('/path/:param/', {} , 
{
        'get':    {method:'GET', 
                   interceptor : {responseError : resourceErrorHandler}},
        'save':   {method:'POST'},
        'query':  {method:'GET', isArray:true, 
                   interceptor : {responseError : resourceErrorHandler}},
        'remove': {method:'DELETE'},
        'delete': {method:'DELETE'}
};

where resourceErrorHandler is a function called on each error on get or query method. For the problem asked, the get method is the only needed. Of course you can apply that to any action.

An other interceptor response exists for $resource to catch a normal response.

 {'get': {method:'GET', interceptor : {response : resourceResponseHandler}},

Interceptors are part of the $http module, you can further read about them in their docs.

Languedoc answered 10/9, 2014 at 16:29 Comment(0)
E
1

Here is a new ES6 example (I use TypeScript) on my ng.resource

resolve: {
    detail: function (myService, $stateParams) {
        return myService.getEventDetail({ id: $stateParams.id }).$promise.then(data => data, error => false );
    }
}

and then in my controller, 'detail' injected into the controller will either resolve to the data (good) or false for error, where I handle the display of 404.

Ethelynethene answered 30/11, 2016 at 21:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.