Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular 2 - routing guard returning observable<boolean>, understanding

I guess this might more of a rxjs understanding topic but the context illustrates my want of it the best :)

So below it the working code inside my PageGuard class, which prevents routing to pages unless a valid jwt exists in localStorage.

CheckForToken() just appends Authorization Header if token exists in localStorage.

public isAuthenticated():Observable<boolean>{
    this.checkForToken();
    let isAuth = new Observable<boolean>(observer => {
        this.http.get(`https://testhan-api.selfbits.io/api/v1/user`,{headers: this.headers}).subscribe(res => {
            if (res.status === 200){
                observer.next(true);
                observer.complete();
            }else{
                observer.next(false);
                observer.complete()
            }
        },err => console.log(err));
    });
    return isAuth
}

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    return this.isAuthenticated()
}

and the routing path looks like this

{ 
    path:'dashboard', 
    component:DashboardComponent, 
    canActivate:PageGuard
}

My question: So far, my understanding is that you need to subscribe to an observable, in order to execute it, like

observable.subscribe(res => //do something with res)

but here I'm only returning an observable, it doesn't get subscribed, but how does the guard evaluate it?

thanks for the clarification!

like image 957
Han Che Avatar asked Aug 28 '26 18:08

Han Che


1 Answers

If you really wanna get down to the nitty gritty... here goes :-)

Most of the work regarding navigation goes on the runNavigate method. The point where it gets to the guards is here, where there's a call to checkGuards which returns an Observable<boolean>. Depending on what type of guard it is, it will call a specific method for that type of guard, that also returns an Observable<boolean>. All of those "specific methods" call a method wrapIntoObservable passing in the result of the guard method. If you look at the wrapIntoObservable source, you will see that it checks for a Observable, a Promise, or a regular value. In either case, an Observable is always returned.

Now going back down the call stack, once all the guard Observables are all merged into an Observable emitting a single boolean value, that observable goes through the process of resolving data for the routes. If the merged guard observable returns false, the new resolve Observable will return an Observable of false. Otherwise it will return an Observable of the resolved data.

In the next step, the resolve Observable gets subscribed to with forEach. If the resolved data is false (false forwarded from the guards), then it will return nothing and the routing stops. Otherwise, anActivatedRoute. From there the rest of the navigation continues.

like image 133
Paul Samsotha Avatar answered Aug 31 '26 06:08

Paul Samsotha