Search code examples
angular7angular-routing

Route Navigation issue when using route guard


I have a route guard:

          import { Injectable } from "@angular/core";
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from "@angular/router";
import { Observable } from "rxjs";
import { ConfigurationService } from "./../configuration.service";
import { LoginServiceService } from '../login-service.service';
import { map } from 'rxjs/operators'
import { of } from 'rxjs';

@Injectable()
export class RoleGuard implements CanActivate {
  activate = false;

  constructor(private loginService: LoginServiceService,
    private router: Router,
    private configService:ConfigurationService
  ) {
  }

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean> | boolean {

    return this.loginService.userRights().pipe(
      map((userRights) => {
        this.filterUserRights(userRights['rights'])
      }),
    );
  }

  filterUserRights(userRights:Array<string>):Observable<boolean> {
    console.log(userRights)
    const requiredRights = ['create_organisation', 'create_tenant', 'create_user'];
    if (requiredRights.some((right) => userRights && userRights.includes(right))) {
      this.activate = true;
    } else {
      this.activate = false;
    }
    return of(this.activate);
  }

}

I have a parent route like :

  { path: "", redirectTo: "mylearning", pathMatch: "full" },
  {
    path: "managepeople",
    component: ManagepeopleComponent,
    canActivate: [RoleGuard],

    children: [
      { path: "", redirectTo: "organisations", pathMatch: "full" },
      {
        path: "organisations",
        component: OrganisationsComponent,
        data: {
          animation: "organisations"
        },

      },
]
}

Im using the role guard on parent route managepeople. The problem is that when i refresh the browser for ex, on route : managepeople/organisations, it does not go to that route but redirects to the root component url.The user rights comes from a service which will take some to be fetched from server. How do i fix this?

My service function:

  userRights() {
    var uiRolesUrl = this.config.restRequestUrl + "userapi/myrights/";
    var observable = this.http.get(uiRolesUrl);
    return observable;
  }

Solution

  • This worked:

    import { Injectable } from "@angular/core";
    import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from "@angular/router";
    import { Observable } from "rxjs";
    import { ConfigurationService } from "./../configuration.service";
    import { LoginServiceService } from '../login-service.service';
    import { map } from 'rxjs/operators'
    import { of } from 'rxjs';
    
    @Injectable()
    export class RoleGuard implements CanActivate {
      activate = false;
    
      constructor(private loginService: LoginServiceService,
        private router: Router,
        private configService:ConfigurationService
      ) {
      }
    
      canActivate(
        next: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
      ): Observable<boolean> | boolean {
        return this.loginService.userRights().pipe(map((userRights) => {
          return this.filterUserRights(userRights['rights']);
        }),
        )
      }
    
      filterUserRights(userRights:Array<string>){
        const requiredRights = ['create_organisation', 'create_tenant', 'create_user'];
        if (requiredRights.some((right) => userRights && userRights.includes(right))) {
          this.activate = true;
        } else {
          this.activate = false;
        }
        return this.activate;
      }
    
    }