Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle resource not found with AngularJS routing

In a traditional data driven web application we often attempt to load a resource based on an ID passed in the URL. If the resource does not exist we return a 404 page.

How should we achieve the same thing in AngularJS? I've followed the AngularJS phone catalog tutorial and am currently doing the following should the resource not exist (note this uses the Angular $resource service):

controllers.controller('PhoneDetailCtrl', ['$scope', '$routeParams', '$location', 'Phone',
  function($scope, $routeParams, $location, Phone) {

    $scope.phone = Phone.get({ phoneId: $routeParams.phoneId }, 
      function(phone) {
        $scope.mainImageUrl = phone.images[0];
      },
      function(response) {
        if (response.status === 404) {
          $location.path('/404'); // show phone not found page
        }
      });
}]);

Is this the recommended approach? Considering I will need to do this on virtually every resource I wondered whether it would be better handled within the $routeProvider?

like image 737
Ben Foster Avatar asked Feb 01 '14 18:02

Ben Foster


2 Answers

I usually use ngRoute and provide resources through resovle:

angular.module('myApp').config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/phone/:phoneId', {
         templateUrl: 'views/phone.html',
         controller: 'PhoneDetailCtrl',
         resolve: {
             phone: ['$route', 'Phone', function($route, Phone) {
                 return Phone.get({ phoneId: $route.current.params.phoneId }).$promise
             }]
         }
    });
}]);

Now phone declared as dependency of this route and route won't be changed when response return an error. Then if you want to show error page you need listen to $routeChangeError event

angular.module('myApp').run(['$rootScope', '$location', function($rootScope, $location) {
   $rootScope.$on('$routeChangeError', function(event, current, previous, error) {
       if(error.status === 404) {
          $location.path('/404');
       }
   });
}]);

If you have multiple resources this approach allow you keep error handling code in one place and clear controllers from this logic that is very convenient

like image 175
just-boris Avatar answered Sep 23 '22 17:09

just-boris


Internally ngResource uses $http so to handle this kind of situations you could use http interceptors

like image 26
dimirc Avatar answered Sep 21 '22 17:09

dimirc