Darwin Tech Darwin Tech - 1 month ago 9
AngularJS Question

Angular UI router handling 404s

I have an app with a service which wraps my API calls:

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


and I'm using UI-Router to transition between states:

concernsApp

.config( function ($stateProvider, $urlRouterProvider) {

$urlRouterProvider.otherwise("/404/");


$stateProvider.state('project', {
url: '/project/:projectId/',
resolve: {
project: function ($stateParams, ConcernService) {
return ConcernService.get('projects/', $stateParams.projectId);
},
},
views: {
...
}
});


I'm moving from using the normal Angualr router and I'm having difficulty understanding how to implement 404s. I can see the
ConcernService
throwing the
console.log
status as rejected, but how do I catch this in the state router?

Any help much appreciated.

Answer

The otherwise() rule is only invoked when no other route matches. What you really want is to intercept the $stateChangeError event, which is what gets fired when something goes wrong in a state transition (for example, a resolve failing). You can read more about that in the state change event docs.

The simplest implementation for what you're trying to do would be something like this:

$rootScope.$on('$stateChangeError', function(event) {
  $state.go('404');
});

Also, since $http itself is built on promises (which resolve resolves), your ConcernService method can be simplified down to a one-liner (I realize you expanded it for debugging purposes, but you could have just as easily chained it, just FYI):

var ConcernService = {

  get: function (items_url, objId) {
    return $http.get(api_url + items_url + objId);
  }
}