badr slaoui
badr slaoui

Reputation: 1063

show/hide components based on roles

I have a dashboard component that will be serving different profiles. For each profile I created a separate component and added it to the main dashboard component :

**dashboard.component.html**

<app-employer-dashboard></app-employer-dashboard>
<app-candidate-dashboard></app-candidate-dashboard>

What i want to achieve is similar to auth guards for routes, add some decoration, so that based on the user profile, activate only the corresponding component. using [hidden]="hasNotAccessToComponent()" seems to be possible but i am wondering if there is a more elegant way to do it.

Upvotes: 0

Views: 2024

Answers (1)

Tushar Walzade
Tushar Walzade

Reputation: 3809

I recommend setting it in your router with canActivate property using route Guards as follows -

So, your routes would be -

const routes: Routes = [
    {
        path: 'employer',
        component: EmployerDashboardComponent,
        canActivate: [AuthGuard]
    },
    {
        path: 'candidate',
        component: CandidateDashboardComponent,
        canActivate: [AuthGuard]
    }
];

Your canActivate method in AuthGuard would be similar to the following -

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

    const currentUser = this.userService.getCurrentUser();
    this.currentUserRole = currentUser ? JSON.parse(currentUser)['role'] : undefined;
    this.currentUserRole = this.currentUserRole ? this.currentUserRole.toLowerCase() : undefined;

    // I stored allowed paths with the same user object
    let allowedPaths = currentUser ? JSON.parse(currentUser)['allowedPaths'] : undefined;

    // obtaining an array of strings for allowed paths
    this.allowedPaths = allowedPaths ? allowedPaths.split(",").map(Function.prototype.call, String.prototype.trim) : undefined;
    const isLoggedIn = this.userService.isLoggedIn();
    if(isLoggedIn) {
        if (this.currentUserRole == 'admin') {
            return true;
        } else {
            return this.validatePath(this.allowedPaths, state.url);
        }
    } else {
        return false;
    }
}

And the method I used to validatePath is as follows -

validatePath(pathArray: Array <string>, path: string): boolean {
    if(!pathArray) {
        return false;
    }

    if(pathArray.includes(path)) {
        return true;
    } else {
        this.router.navigate(['inaccessible']);
        return false;
    }
}

Upvotes: 3

Related Questions