J'ai un AuthGuard (utilisé pour le routage) qui implémente CanActivate .
canActivate() {
return this.loginService.isLoggedIn();
}
Mon problème est que le résultat CanActivate dépend d'un http-get-result - le LoginService renvoie un observable .
isLoggedIn():Observable<boolean> {
return this.http.get(ApiResources.LOGON).map(response => response.ok);
}
Comment puis-je les réunir - faire dépendre CanActivate d'un état backend?
# # # # # #
EDIT: Veuillez noter que cette question date de 2016 - un stade très précoce d'angular / router a été utilisé.
canActivate()
peut renvoyer unObservable
, assurez-vous simplement que leObservable
a terminé (ie.observer.complete()
).take(1)
opérateur Rx pour atteindre la totalité du flux, que faire si j'oublie de l'ajouter?Réponses:
Vous devez mettre à jour "@ angular / router" vers la dernière version. par exemple "3.0.0-alpha.8"
modifier AuthGuard.ts
Si vous avez des questions, demandez moi!
la source
isLoggedIn()
c'est unPromise
, vous pouvez le faireisLoggedIn().then((e) => { if (e) { return true; } }).catch(() => { return false; });
J'espère que cela aidera les futurs voyageurs!import 'rxjs/add/observable/of';
Mise à jour de la réponse de Kery Hu pour Angular 5 et RxJS 5.5 où l'
catch
opérateur est déconseillé. Vous devez maintenant utiliser l'opérateur catchError conjointement avec les opérateurs pipe et 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); }) ); } }
la source
canActivate () accepte
Observable<boolean>
comme valeur renvoyée. Le garde attendra la résolution de l'observable et examinera la valeur. Si «vrai», il passera la vérification, sinon (toute autre donnée ou erreur générée) rejettera l'itinéraire.Vous pouvez utiliser l'
.map
opérateur pour transformer leObservable<Response>
enObservable<boolean>
comme ceci:la source
Je l'ai fait de cette façon:
Comme vous pouvez le voir, j'envoie une fonction de secours à userService.auth que faire si l'appel http échoue.
Et dans userService j'ai:
la source
Cela peut vous aider
la source
CanActivate fonctionne avec Observable mais échoue lorsque 2 appels sont effectués comme CanActivate: [Guard1, Guard2].
Ici, si vous retournez un Observable de false de Guard1, il vérifiera également Guard2 et autorisera l'accès à la route si Guard2 renvoie true. Pour éviter cela, Guard1 doit retourner un booléen au lieu de Observable ou boolean.
la source
dans canActivate (), vous pouvez retourner une propriété booléenne locale (par défaut à false dans votre cas).
Et puis dans le résultat du LoginService, vous pouvez modifier la valeur de cette propriété.
la source