0

We have a routing guard for CanActivate that works fine when clicking between links on the site, but fails when we fully refresh the browser (i.e. it redirects to the home page, the same behaviour as if CanActivate returns false).

This is my guard

@Injectable()
export class PermissionCheckGuard implements CanActivate {
    constructor(private userPermissionService: UserPermissionService) { }

    canActivate(
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
    ): Observable<boolean> | Promise<boolean> | boolean {
        let permissionTag = route.data["permissionTag"] as string;

        let hasPermission$ = this.userPermissionService.hasPermission(null, SubjectType.Site, permissionTag, null);

        hasPermission$.subscribe(x => {
            console.log(x);
        });

        return hasPermission$;
    }
}

This is my router config:-

path: 'security/security-example', component: SecurityExampleComponent, canActivate: [PermissionCheckGuard], data: { permissionTag: 'Site_Permission_1' }

In case it matters this is the hasPermission function

 public hasPermission(userId: string, subjectType: SubjectType, permissionTag: string, subjectId: string): Observable<boolean> {

        if (userId == null) {
            userId = 'Current';
        }

        const url = this.apiUrlBuilder.create('Security', 'Users', userId, 'Permission', {
            permissionTag: permissionTag,
            subjectType: subjectType,
            subjectId: subjectId
        });

        return this.http.get(url)
            .map<Response, boolean>((response: Response) => {
                return <boolean>response.json();
            })
            .catch((error) => {
                return this.errorHandlingService.ToNotification(error, this);
            })
    }

I don't see what I'm doing wrong, the guard is returning an observable and the console log is always returning true. Is this an issue with angular or is there a mistake in my code?

Jacob Regan
  • 67
  • 1
  • 1
  • 9

1 Answers1

0

I guess somehow it is resolved before you get response. Try using subject here.

import { Subject } from 'rxjs';

canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
): Observable<boolean> | Promise<boolean> | boolean {
    let permissionTag = route.data["permissionTag"] as string;

    let hasPermission$ = this.userPermissionService.hasPermission(null, SubjectType.Site, permissionTag, null);

 const subject: Subject<boolean> = new Subject();
    hasPermission$.subscribe(x => {
        console.log(x);
        subject.next(x);
    });

    return subject.asObservable();
}
Yousef khan
  • 2,764
  • 3
  • 14
  • 16
  • Thanks, I'll try this. If it is being resolved before we get a response is this a bug with angular? – Jacob Regan Nov 14 '18 at 10:56
  • @JacobRegan I am not sure. It is just a guess. Got the idea from this thread. See if it helps https://stackoverflow.com/questions/45255745/angular2-guard-not-working-on-page-refresh – Yousef khan Nov 14 '18 at 11:00
  • Unfortunately this didn't work either, it still redirects to the home page on full reload – Jacob Regan Nov 14 '18 at 11:08
  • It will be easier to find the cause if you could add your code on https://stackblitz.com/ – Yousef khan Nov 14 '18 at 11:20
  • Can you inspect in network that how many times your hasPermission request is sent when you reload? Just change the `subscribe` to `map` – Yousef khan Nov 14 '18 at 11:27