0

I have a sidebar menu. I would like to hide some paths, based on user's role. Here I have ROUTES like this:

export const ROUTES: RouteInfo[] = [
  {
    path: '/overview',
    title: 'Overview',
    type: 'link',
    icontype: 'search'
  },
  {
    path: '/loyalty',
    title: 'Loyalty',
    type: 'sub',
    icontype: 'loyalty',
    collapse: 'loyalty',
    children: [
      { path: 'programs', title: 'Programs', ab: 'P', icontype: 'accessibility' },
      { path: 'members', title: 'Members', ab: 'M', icontype: 'group_add' },
      { path: 'segments', title: 'Segments', ab: 'S', icontype: 'data_usage' },
      { path: 'emailautomation', title: 'Email automation', ab: 'EA', icontype: 'mail' }
    ]
  },

... etc

My sidebar appears like as fallows:

this.menuItems = ROUTES.filter(menuItem => menuItem);

I'd like to filter children array, taking into consideration user's role.

How can I filter these ROUTES to hide, for example, path 'programs' ?

8
  • What's the criteria are you trying to filter by? Commented Dec 23, 2019 at 14:55
  • Seems you're looking for Route Guards(Angular Doc) Commented Dec 23, 2019 at 14:57
  • @ulmas lt's say, if user has a role 'user' I would like to generate side menu without path 'programs'. So, children array should look like [ { path: 'members', title: 'Members', ab: 'M', icontype: 'group_add' }, { path: 'segments', title: 'Segments', ab: 'S', icontype: 'data_usage' }, { path: 'emailautomation', title: 'Email automation', ab: 'EA', icontype: 'mail' }] Commented Dec 23, 2019 at 14:57
  • @Chenna I don't think so ... Route Guards wont give me the access to this route, but it still be rendered in the side menu Commented Dec 23, 2019 at 14:58
  • @ulmas i just want to loop through ROUTES array, find children array and filter it, hiding some objects Commented Dec 23, 2019 at 15:08

2 Answers 2

1
children: [
  { path: 'programs', title: 'Programs', ab: 'P', icontype: 'accessibility', role: ['admin'] },
  { path: 'members', title: 'Members', ab: 'M', icontype: 'group_add', role: ['admin', 'editor'] },
  { path: 'segments', title: 'Segments', ab: 'S', icontype: 'data_usage' }, // items with no role are public
  { path: 'emailautomation', title: 'Email automation', ab: 'EA', icontype: 'mail' }
]   

I don't know how and where you keep your user roles, so let's say there is a field in the component that user roles are there:

userRoles: string[] = ['admin'];

In your view:

<ul class="nav"> 
  <li routerLinkActive="active" *ngFor="let childitem of menuitem.children" class="nav-item"
    [class.d-none]="childitem.role && !userRoles.includes(childitem.role)"> 
    <a [routerLink]="[menuitem.path, childitem.path]" class="nav-link"> 
      <i class="material-icons">{{ childitem.icontype }}</i> 
      <span class="sidebar-normal">{{ childitem.title }}</span> 
    </a> 
  </li> 
</ul>
Sign up to request clarification or add additional context in comments.

Comments

1

I didn't find any method to block access just by looping through routes, but I hope this will be approach useful

In SideBar Component

checkAccess(): boolean { //write your own custom
    if (sessionStorage.getItem('userrole') == 'admin'){ // write your own custom user role check
       return true;
    }
    return false;
}

To remove User Links in your sidebar UI

<a [routerLink]=['/programs'] *ngIf="checkAccess()">Programs</a>

You can additionally block access from Router Level itself

In routing module

{
   path: 'programs', 
   title: 'Programs',
   ab: 'P', icontype: 'accessibility', 
   canActivate: [AuthorizeGuard],
   //canActivateChlid: [AuthorizeGuard]
},

In Authorize Guard

canActivate(): boolean | Observable<boolean> {
    if (sessionStorage.getItem('userrole') == 'admin'){ // write your own custom user role check
       return true;
    }
    return false;
}

2 Comments

This is good approach. But I don't have separate links in my sidebar component.. I have *ngFor like this. <ul class="nav"> <li routerLinkActive="active" *ngFor="let childitem of menuitem.children" class="nav-item"> <a [routerLink]="[menuitem.path, childitem.path]" class="nav-link"> <i class="material-icons">{{ childitem.icontype }}</i> <span class="sidebar-normal">{{ childitem.title }}</span> </a> </li> </ul>
then you can add *ngIf="hasAccess(menuitem)" in <li> element and in your component file hasAccess(menuItem) which returns boolean value. By doing this only the links the which user has permission will be visible.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.