0

I have resolver and guard.On my base route path i have resolver which makes http call - to get token for authentication.

Inside child routes i have guards for permission. Always guard is executed before the resolver - so the problem is that first my guard is executed and after that - my guard.

So the resolver looks like this:

import { Injectable, Injector } from '@angular/core';
import { Resolve, RouterLink, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { tap, catchError } from 'rxjs/operators';
import { AuthStoreService } from '@services/auth-store.service';
import { LoginService } from 'src/api/controllers/Login';
import { OAuthService } from 'angular-oauth2-oidc';

@Injectable()
export class TokenResolver implements Resolve<any> {

    constructor(
        public injector: Injector,
        public authStore: AuthStoreService,
        public loginService: LoginService,
        private oauthService: OAuthService,
        public router: Router
    ) { }

    resolve(): Observable<any> {
        let resolver =  this.loginService.token({ token: this.oauthService.getAccessToken() }).pipe(
            tap(response => { 
                console.log('res', response);
                this.authStore.setData(response);
                this.authStore.isSetDataCalled = true;
                return response;
            },
            ), catchError(err => {
                console.log('err', err);
                this.router.navigate(['/405']);
                return Observable.throw(err);
            }));

            
            console.log('resolver', resolver);
            return resolver;
    }
}

How can i await the call in my guard

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, Router } from '@angular/router';
import { AuthStoreService } from '@core/services/auth-store.service';

@Injectable()
export class HasPermissionGuard implements CanActivate {

    constructor(
        public authStore: AuthStoreService,
        private router: Router // Use this to redirect to 403
    ) { }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        
        if (!this.authStore.hasUserInfo()) {
            return true;
        }
        if (this.authStore.hasPermission(route.data.permission)) {
            return true;
        }

        this.router.navigate(['/403']); // Toggle this to redirect to 403 route
        return false;
    }
}
sdsd
  • 447
  • 3
  • 20

1 Answers1

1

You can wait response like this :

@Injectable()
export class HasPermissionGuard implements CanActivate {

    constructor(
        public authStore: AuthStoreService,
        private router: Router // Use this to redirect to 403
    ) { }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
        return new Observable((subscriber) => {
            this.TokenResolver.resolve()
                .subscribe(response => {
                    // if (!this.authStore.hasUserInfo()) {
                    //     subscriber.next(true);
                    // }
                    // if (this.authStore.hasPermission(route.data.permission)) {
                    //     subscriber.next(true);
                    // }
                    if (response)
                        subscriber.next(true);
                    else
                        this.router.navigate(['/403']); // Toggle this to redirect to 403 route
                });
        });
    }
}

For more information, canActivate can return an observable. So, you can wait an observable and return a new observable again.

Piva Gregory
  • 442
  • 2
  • 13