O que estou tentando alcançar
Gostaria de fazer a transição para um determinado estado (login), caso uma solicitação $ http retorne um erro 401. Portanto, criei um interceptor $ http.
O problema
Quando estou tentando inserir '$ state' no interceptador, recebo uma dependência circular. Por que e como corrigi-lo?
Código
//Inside Config function
var interceptor = ['$location', '$q', '$state', function($location, $q, $state) {
function success(response) {
return response;
}
function error(response) {
if(response.status === 401) {
$state.transitionTo('public.login');
return $q.reject(response);
}
else {
return $q.reject(response);
}
}
return function(promise) {
return promise.then(success, error);
}
}];
$httpProvider.responseInterceptors.push(interceptor);
fonte
$injector
serviço no seu interceptador e liga para$injector.get()
onde precisa obter o$state
serviço.$httpProvider.responseInterceptors.push
não funcionará mais se você estiver usando versões posteriores do Angular. Use em$httpProvider.interceptors.push()
vez disso. Você precisaria modificar ointerceptor
também. Enfim, obrigado pela resposta maravilhosa! :)A pergunta é uma duplicata do AngularJS: injetando serviço em um interceptor HTTP (dependência circular)
Estou repostando minha resposta a partir desse tópico aqui:
Uma correção melhor
Eu acho que usar o injetor $ diretamente é um antipadrão.
Uma maneira de quebrar a dependência circular é usar um evento: em vez de injetar $ state, injete $ rootScope. Em vez de redirecionar diretamente, faça
mais
Dessa forma, você separou as preocupações:
fonte
A solução de Jonathan foi ótima até eu tentar salvar o estado atual. No ui-router v0.2.10, o estado atual não parece ser preenchido no carregamento inicial da página no interceptador.
Enfim, resolvi usando o evento $ stateChangeError . O $ stateChangeError evento dá-lhe tanto para e de estados, bem como o erro. É bem bacana.
fonte