angularangular-routingrouterlinkactive

Angular routerLinkActive not working as expected


I am working on a rather simple project but this issue has me stumped!

I have routing setup and working correctly except for one small issue with the routerLinkActive not staying activated.

I can't embed an image in a question yet, so please follow the link to take a look at the results I am getting

Routing Results

When I go to: http://localhost:4200/1 the '1' menu item correctly shows as active in the nav bar. If I then go to a child route: http://localhost:4200/1/top100 the '1' menu still stays set as active. This is exactly how I want it to work.

However in a very similar setup I have the '4' menu item go to: http://localhost:4200/2/A. This correctly shows the '4' in the top nav bar as active and the 'Test A' button as active. But when I go to http://localhost:4200/2/B then the 'Test B' button correctly shows as active but the main nav bar as lost its active flag on the '4'.

Code snippets attached below:

Nav Bar

<ul class="navbar-nav">
  <li class="nav-item" routerLinkActive="active">
    <a class="nav-link" routerLink="/1">1</a>
  </li>
  <li class="nav-item" routerLinkActive="active">
    <a class="nav-link" [routerLink]="['/notUsed', 'notUsed']">2</a>
  </li>
  <li class="nav-item" routerLinkActive="active">
    <a class="nav-link" [routerLink]="['/notUsed', 'notUsed']">3</a>
  </li>
  <li class="nav-item" routerLinkActive="active">
    <a class="nav-link" [routerLink]="['/2', 'A']">4</a>
  </li>
  <li class="nav-item" routerLinkActive="active">
    <a class="nav-link" routerLink="/notUsed">5</a>
  </li>
</ul>

Button Group

<div class="btn-group-vertical fixedWidthButtonHonour mb-3" role="group" aria-label="Senior Grades">
  <button type="button" class="btn btn btn-outline-danger" [routerLink]="['/2', 'A']" routerLinkActive="active">Test A</button>
  <button type="button" class="btn btn btn-outline-danger" [routerLink]="['/2', 'B']" routerLinkActive="active">Test B</button>
</div>

Routes

const appRoutes: Routes = [
  { path: '', component: HomeComponent, pathMatch: 'full' },
  { path: '1', component: Component1 },
  { path: '1/top100/:name', component: ComponentTop100 },
  { path: '2', component: Component2 },
  { path: '2/:viewType', component: Component2 },
  { path: '**', redirectTo: '/', pathMatch: 'full' }
];

I can't work out the difference between the two examples. Great if anyone has any insights or working demo's that achieve what I am after.

Thanks David


Solution

  • The problem is that you expect routerLinkActive on ['/2', 'A'] to get active when you are at ['/2', 'B']. This is not how it works. You should create a routerLinkActive on a /2 link.

    If you don't mind to always redirect /2 to /2/A, you can do the following:

    In your Nav Bar:

    <li class="nav-item" routerLinkActive="active">
      <a class="nav-link" routerLink="/2">4</a>
    </li>
    

    In your App Routes

    const appRoutes: Routes = [
      { path: '', component: HomeComponent, pathMatch: 'full' },
      { path: '1', component: Component1 },
      { path: '1/top100/:name', component: ComponentTop100 },
      { path: '2', redirectTo: '2/A', pathMatch: 'full' },
      { path: '2/:viewType', component: Component2 },
      { path: '**', redirectTo: '/', pathMatch: 'full' }
    ];
    

    Another solution could be to just manually add the [class.active] based on your current router path