Eu tenho um AuthGuard (usado para roteamento) que implementa CanActivate .
canActivate() {
return this.loginService.isLoggedIn();
}
Meu problema é que o CanActivate-result depende de um http-get-result - o LoginService retorna um Observable .
isLoggedIn():Observable<boolean> {
return this.http.get(ApiResources.LOGON).map(response => response.ok);
}
Como posso uni-los - fazer CanActivate depender de um estado de back-end?
# # # # # #
EDIT: Por favor, note que esta questão é de 2016 - um estágio muito inicial do angular / roteador foi usado.
# # # # # #
angular
angular2-routing
angular2-http
Philipp
fonte
fonte
canActivate()
pode retornar umObservable
, apenas certifique-se de que oObservable
foi concluído (ou seja.observer.complete()
).take(1)
operador Rx para atingir a totalidade do fluxo. E se eu esquecer de adicioná-lo?Respostas:
Você deve atualizar "@ angular / router" para o mais recente. por exemplo, "3.0.0-alpha.8"
modificar AuthGuard.ts
Se você tiver alguma dúvida, pergunte-me!
fonte
isLoggedIn()
seja umPromise
, você pode fazerisLoggedIn().then((e) => { if (e) { return true; } }).catch(() => { return false; });
Espero que isso ajude os futuros viajantes!import 'rxjs/add/observable/of';
Atualizando a resposta de Kery Hu para Angular 5+ e RxJS 5.5 onde o
catch
operador está obsoleto. Agora você deve usar o operador catchError em conjunto com os operadores pipe e lettable .import { Injectable } from '@angular/core'; import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { Observable } from 'rxjs/Observable'; import { catchError, map} from 'rxjs/operators'; import { of } from 'rxjs/observable/of'; @Injectable() export class AuthGuard implements CanActivate { constructor(private loginService: LoginService, private router: Router) { } canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> { return this.loginService.isLoggedIn().pipe( map(e => { if (e) { return true; } else { ... } }), catchError((err) => { this.router.navigate(['/login']); return of(false); }) ); } }
fonte
canActivate () aceita
Observable<boolean>
como valor retornado. O guarda vai esperar que o Observável resolva e olhar para o valor. Se for 'verdadeiro', ele passará na verificação, senão (quaisquer outros dados ou erro lançado) rejeitará a rota.Você pode usar o
.map
operador para transformar oObservable<Response>
paraObservable<boolean>
like assim:fonte
Eu fiz desta forma:
Como você pode ver, estou enviando uma função de fallback para userService.auth, o que fazer se a chamada http falhar.
E em userService eu tenho:
fonte
Isso pode te ajudar
fonte
CanActivate funciona com Observable, mas falha quando 2 chamadas são feitas como CanActivate: [Guard1, Guard2].
Aqui, se você retornar um Observable of false de Guard1, ele também verificará em Guard2 e permitirá o acesso à rota se Guard2 retornar true. Para evitar isso, Guard1 deve retornar um booleano em vez de Observable de boolean.
fonte
em canActivate (), você pode retornar uma propriedade booleana local (o padrão é false no seu caso).
E então, no resultado do LoginService, você pode modificar o valor dessa propriedade.
fonte