2

What is the easiest way to detect $http errors from the server and delete the token if ANY of the calls cause a 401 error? For example, if a session expires while the user is not using the app, when they return to the web app the token is no longer valid. If I send back a 401 error during an API call I need to notice this and make the user log back in.

Currently, in the Chrome Developer Tools, I can see the 401 error but Satellizer does not delete the token (thought it did at one time).

I tried creating an httpInterceptor, but received Circular Dependency error:

apiLogoutInterceptor.$inject = ['$q', '$auth'];
function apiLogoutInterceptor ($q, $auth) {
    var service = this;
    service.responseError = function (response) {
        if (response.status == 401) {
            $auth.removeToken();
            window.location = '/login';
        }
        return $q.reject(response);
    };
}

configureApiLogout.$inject = ['$httpProvider'];
function configureApiLogout ($httpProvider) {
    $httpProvider.interceptors.push('apiLogoutInterceptor');
}
G. Deward
  • 1,542
  • 3
  • 17
  • 30

1 Answers1

2

You can workaround the cyclic dependency by just injecting the $injector service and fetching your required dependencies manually. For an example, see this post: AngularJS: Injecting service into a HTTP interceptor (Circular dependency)

Additionally, I don't see any reason for using var service = this as it is enough to return a simple object containing the handler method for the responseError key like this:

function($injector, ...) {
  return {
    'responseError': function(err) { /* your handler logic */ }
  }
}
Community
  • 1
  • 1
Andreas Jägle
  • 11,632
  • 3
  • 31
  • 31
  • Thanks for the link. It helped me get around the problem. I'm hoping there is an 'official' way of doing this within Satellizer. If I can't find one, I'll edit my question, title, and accept the answer since it worked. – G. Deward Feb 27 '16 at 19:26
  • That is a common issue when you need a service that has access to $http directly or even indirectly (e.g. via $state - from the routing). You can either use the $injector service or inject the $rootscope and broadcast an event (which also breaks up the cycle). Depends on our use case which fits better. If you cannot modify the service you need to call, the $injector will be the way to go. – Andreas Jägle Feb 27 '16 at 20:13