Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS handle rejected response with UI-Router

I have a Service which wraps my API calls in Angular:

var ConcernService = {

    list: function (items_url) {
        var defer = $q.defer();
        $http({method: 'GET', 
            url: api_url + items_url})
            .success(function (data, status, headers, config) {
                defer.resolve(data, status);
            })
            .error(function (data, status, headers, config) {
                defer.reject(data, status);
            });
        return defer.promise;
    },

Then my app config, with UI-Router:

    .config(function($stateProvider){

        $stateProvider

        .state('default', {
            url: '/',
            resolve: {
                tasks: function ($stateParams, ConcernService) {
                    return ConcernService.list('tasks/').then(
                        function (tasks)   { return tasks; },
                        function (reason)  { return []; }
                    );
                },
                ...
            }
        }
    });

This is the most basic configuration I could get away with, which basically just returns an empty object if a 403, 404 etc is encountered and I can handle that in the view, template.

My question is, what is the best approach for getting the other detail to the view/ template, such as the rejection reason and status. Should it be returned in the tasks object, or separately?

like image 349
Darwin Tech Avatar asked May 26 '14 20:05

Darwin Tech


1 Answers

Well, first of all, your first bit of code has the deferred anti pattern, let's fix that:

list: function (items_url) {
    return $http.get(api_url + items_url); // $http already returns a promise
},

Also note, that deferred rejections and fulfillments are single value, so your multiple return values don't really work here.

Now, let's look at the router. First of all, your first fulfillment handler is redundant.

.state('default', {
        url: '/',
        resolve: {
            tasks: function ($stateParams, ConcernService) {
                return ConcernService.list('tasks/'); // result.data contains the data here
            },
            ...
        }

Now, the problem we have here is what happens in case of a rejection?

Well, listen to $stateChangeError:

$rootScope.$on('$stateChangeError', 
function(event, toState, toParams, fromState, fromParams, error){ ... })

Here, you can listen to change state failures from rejections.

like image 177
Benjamin Gruenbaum Avatar answered Oct 06 '22 17:10

Benjamin Gruenbaum