Tengo un AuthGuard (utilizado para enrutamiento) que implementa CanActivate .
canActivate() {
return this.loginService.isLoggedIn();
}
Mi problema es que el resultado de CanActivate depende de un http-get-result; el LoginService devuelve un Observable .
isLoggedIn():Observable<boolean> {
return this.http.get(ApiResources.LOGON).map(response => response.ok);
}
¿Cómo puedo unirlos? ¿Hacer que CanActivate dependa de un estado de backend?
# # # # # #
EDITAR: Tenga en cuenta que esta pregunta es de 2016: se ha utilizado una etapa muy temprana de angular / enrutador.
# # # # # #
angular
angular2-routing
angular2-http
Philipp
fuente
fuente
canActivate()
puede devolver unObservable
, solo asegúrese de que seObservable
haya completado (es decirobserver.complete()
).take(1)
operador Rx para lograr la finalización de la secuencia. ¿Qué pasa si me olvido de agregarlo?Respuestas:
Debe actualizar "@ angular / enrutador" a la última versión. por ejemplo, "3.0.0-alpha.8"
modificar AuthGuard.ts
Si tienes alguna duda, pregúntame!
fuente
isLoggedIn()
es unPromise
, puede hacerloisLoggedIn().then((e) => { if (e) { return true; } }).catch(() => { return false; });
.import 'rxjs/add/observable/of';
Actualización de la respuesta de Kery Hu para Angular 5 y RxJS 5.5 donde el
catch
operador está en desuso. Ahora debería usar el operador catchError junto con los operadores de canalización y permitible .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); }) ); } }
fuente
canActivate () acepta
Observable<boolean>
como valor devuelto. El guardia esperará a que el Observable se resuelva y verá el valor. Si es 'verdadero', pasará la verificación, de lo contrario (cualquier otro dato o error arrojado) rechazará la ruta.Se puede utilizar el
.map
operador para transformar elObservable<Response>
deObservable<boolean>
este modo:fuente
Lo he hecho de esta manera:
Como puede ver, estoy enviando una función de respaldo a userService.auth qué hacer si falla la llamada http.
Y en userService tengo:
fuente
Esto puede ayudarte
fuente
CanActivate funciona con Observable pero falla cuando se realizan 2 llamadas como CanActivate: [Guard1, Guard2].
Aquí, si devuelve un Observable de falso de Guard1, también comprobará Guard2 y permitirá el acceso a la ruta si Guard2 devuelve verdadero. Para evitar eso, Guard1 debería devolver un booleano en lugar de Observable de boolean.
fuente
en canActivate (), puede devolver una propiedad booleana local (por defecto es falso en su caso).
Y luego, en el resultado de LoginService, puede modificar el valor de esa propiedad.
fuente