Angular 2 get current route in guard
Asked Answered
B

3

40

I have an AccessGuard class in my project which its work is to determine if user can access to the route or not. I used the router.url to get the current route but the url returns the route before navigation to the new route like I'm in the users route and I click on the candidates route so the url returns users instead of candidates which I want that to validate access to the route this is my route file:

const routes:Routes = [
{
    path:'',
    component:PanelComponent,
    canActivate:[AuthGuard,AccessGuard],
    canActivateChild:[AuthGuard,AccessGuard],
    children:[
        {
            path:'dashboard',
            component:DashboardComponent
        },
        {
            path:'users',
            component:UsersComponent
        },
        {
            path:'users/:id',
            component:ShowUserComponent
        },
        {
            path:'candidates',
            component:CandidatesComponent
        },
        {
            path:'permissions',
            component:PermissionsComponent
        },
        {
            path:'holidays',
            component:HolidaysComponent
        },
        {
            path:'candidate/:id',
            component:CandidateComponent
        },
        {
            path:'salary/create',
            component:InsertSalaryComponent
        },
        {
            path:'document/create',
            component:InsertDocumentComponent
        },
        {
            path:'leave/create',
            component:InsertLeaveComponent
        }
    ]
}

];

and this is my access guard:

permissions;
currentRoute;
constructor(private authService:AuthService,private router:Router){
    this.permissions = this.authService.getPermissions();
}

canActivate(){
    return this.checkHavePermission();
}

canActivateChild(){
    console.log(this.router.url);
    return this.checkHavePermission();
}

private checkHavePermission(){
    switch (this.router.url) {
        case "/panel/users":
            return this.getPermission('user.view');
        case '/panel/dashboard':
            return true;
        case '/panel/candidates':
            return this.getPermission('candidate.view');
        default:
            return true;
    }
}


getPermission(perm){
    for(var i=0;i<this.permissions.length;i++){
        if(this.permissions[i].name == perm ){
            return true;
        }
    }
    return false;
}
Beattie answered 28/9, 2016 at 12:15 Comment(0)
V
71

You need to use the method parameters to see the target route:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
  console.log(state.url);//'candidates'
}

canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot)
Vandiver answered 28/9, 2016 at 12:24 Comment(4)
I just have question I removed the ActivatedRouteSnapshot from parameters and the state.url returned an array but if the ActivatedRouteSnapshot is in arguments it's passes the actual url why?Beattie
You should not remove the ActivatedRouteSnapshot from parameters even if you just want to use the RouterStateSnapshot parameter. The parameters are defined by position. The first parameter will always be the ActivatedRouteSnapshot and its url field is an array. The second parameter will always be the RouterStateSnapshot parameter and its url field is a string. Hope it helps.Vandiver
beware: if your url has queryparams, you might have to do this: console.log(state.url.substring(0, state.url.indexOf("?")));Solubilize
How I check path with param? For example: When I have /posts/:id state.url returns /posts/5Beacon
C
5

this could help you:

  1. Import ActivatedRouteSnapshot and RouterStateSnapshot:

    import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';

  2. Signature in the canActivate:

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable {}

  3. Check the state:

    console.log("route-access",state);

Your Guard file would look something like this:

    import { Injectable } from '@angular/core';
    import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
    import { Observable } from 'rxjs';
    import { AutenticacionService } from 'app/services/index';
    @Injectable()
    export class AuthGuard implements CanActivate {
        constructor(private _router: Router, private auth:AutenticacionService) {}
    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<boolean> {
        // console.log("route-access",state);
        let _url:string="";
        state.url.split("/").forEach(element => {
            if(_url==="")
                if(element!=="")
                    _url=element;
        });
        // console.log(_url);
        return this.auth.check(_url)
          .map((result) => {
                    if (result) {
                        return true;
                    } else {
                        this._router.navigate(['/']);
                        return false;
                    }
                });  
    }

}
Chrisoula answered 1/5, 2017 at 15:45 Comment(0)
I
2

Current URL can be returned from RouterStateSnapshot as shown below,

    import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';    

    canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot){
      console.log(state.url);  
      ...
    }
Illinois answered 11/11, 2018 at 8:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.