$ location.path does not work with http interceptor

this is your pretty straight forward setup, I have an http interceptor that searches for 401s, if found, redirects to the login page:

function($location, $q) { return { request: function (config) { return config || $q.when(config); }, requestError: function(request){ return $q.reject(request); }, response: function (response) { return response || $q.when(response); }, responseError: function (response) { if (response && response.status === 401) { $location.path('/login'); } return $q.reject(response); } }; } 

The problem is that the call to $location.path('/login') does not work, the path is completely ignored, and I stay on the route (albeit an empty page) that I was on when my session expired. One possible way to solve the problem is to use the traditional window.location = '/#!/login'; but I believe that it will be less than ideal. I also found that if I delete the line return $q.reject(response); , I get her work, BUT this introduces another error where the property of the response data cannot be found (the solution is discussed here: Angular.js $ http.post TypeError: Cannot read the property data of 'undefined ).

I am running angular 1.2.21.

Any ideas on what could be happening here? Returning to window.location is not the end of the world, but I would like a beautiful solution to this mystery :).

Thanks in advance.

+6
source share
1 answer

I have the same problem.

I'm not sure, but it looks like $location.path(...) does not change location, because the application waits until all promises are resolved and the promise inside the interceptor is rejected ( return $q.reject(response); )

In my case, the service that makes the HTTP request is placed inside the resolve section of the state of the UI router, so I can use the $stateChangeError event to handle the error. (for ngRoute use the $ routeChangeError event)

Hope this can help you :)

NB My application backend returns custom error messages to 401 response body

PS There must be some better solution.

UPDATE:

More universal workaround:

interceptor inside module.config

 ... responseError: function (response) { if (response && response.status === 401) { $rootScope.$emit('loginRequired'); } return $q.reject(response); } ... 

and an event handler somewhere in the module.run section

 $rootScope.$on('loginRequired', function() { $location.path('/login'); }); 

(I tested the handler with $state.go('login') , but $location.path('/login'); should work too :))

+2
source

Source: https://habr.com/ru/post/974579/


All Articles