2016-07-14 5 views
1

Ich benutze einen AuthGuard, um meine Routen zu schützen, und stelle sicher, dass ein Benutzer korrekt angemeldet ist, bevor er das Dashboard der App sehen kann.Angular2 benötigt das Ergebnis eines asynchronen Abrufs, um Zugriff auf eine Route zu ermöglichen

AuthGuard:

canActivate(
    next: ActivatedRouteSnapshot, 
    state: RouterStateSnapshot 
) { 
    // return true; 
    return this.userService.getValidLoginCheck(); 
} 

jedoch Der getValidLoginCheck() keinen boolean zurückgeben:

getValidLoginCheck(): boolean { 
    let headers = new Headers(); 

    let options = new RequestOptions({ headers: headers }); 

    headers.append('authorization', this.getToken()); 

    this.http.get(this.baseUrl + 'api/auth/checkToken', options) 
     .map(res => res.json()) 
     .subscribe(data => {return data.message === 'valid token' }); 

    } 

Ich weiß, warum dies geschieht, aber wie kann ich die getValid ... Funktion warten zu lassen für das http.get zu beenden, damit ich meine Routen richtig bewachen kann?

Antwort

1

Sie können dies beobachtbar durch Rückkehr erreichen aus kann

allowed: Observable<boolean> 
getValidLoginCheck(): boolean | Observable<boolean> { 
    let headers = new Headers(); 

    let options = new RequestOptions({ headers: headers }); 

    headers.append('authorization', this.getToken()); 
//save URL from routerStateSnapshot from canActivate like URL = state.url 
    this.http.get(this.baseUrl + 'api/auth/checkToken', options) 
     .map(res => res.json()) 
     .subscribe(data => { this.allowed = Observable.of(true); 

this.router.navigateByUrl (URL) aktivieren; return data.message === 'gültiges Token'}, err => {this.allowed = Observable.of (true);}) Rückgabe this.allowed;

+0

Die App wird geladen, aber nicht die Komponente, da das Observable zunächst undefiniert ist. Wie kann ich warten lassen, bis es nicht definiert ist, etwas zurückzugeben? –

+0

Was bedeutet, dass etwas zurückgeben sollte, bis canActivate return true. Möchten Sie den Wartezustand auf der Benutzeroberfläche anzeigen? –

+0

zeigt die Komponente nicht, wenn sie auf true gesetzt ist –

2

Die CanActivate Methode akzeptiert drei Arten von Antworten (beobachtbare, Versprechen und boolean), hier ist die Signatur der Methode:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean; 

So können Sie die Vorteile der beobachtbaren Reaktion nehmen und drehen Sie Ihren Dienst des beobachtbaren in ein beobachtbares wie folgt aus:

canActivate(
    next: ActivatedRouteSnapshot, 
    state: RouterStateSnapshot 
) { 

     return new Observable<boolean>((observer: Observer<boolean>) => { 
     this.userService.getValidLoginCheck() 
     .subscribe(data => {observer.next(data.message === 'valid token')}, 
      error => { console.log("error while calling getValidLoginCheck"); observer.next(false)}); 
     observer.complete(); 
     }); 
} 

Sie sollten eine beobachtbare von Ihrem Service zurückkehren:

getValidLoginCheck(): Observable<Response> { 
    let headers = new Headers(); 

    let options = new RequestOptions({ headers: headers }); 

    headers.append('authorization', this.getToken()); 

    return this.http.get(this.baseUrl + 'api/auth/checkToken', options) 
     .map(res => res.json()); 
    } 

Dies ist, was ich getan habe und es funktioniert für mich, ich bevorzuge eine Methode innerhalb der Subskribieren und senden Sie den Beobachter und die HTTP-Antwort und dann die Antwort in der isolierten Methode, aber das ist meine persönliche Präferenz, ich hoffe es hilft.

Verwandte Themen