24

RouterLinkActive is not working when using a dynamically generated link when navigating through the app itself.

e.g. in my top navigation i have this;

<a [routerLink]=['user', currentUser.name] routerLinkActive='active'>{{currentUser.name}}</a>

Whilst the hardcoded version would work.

<a [routerLink]=['user','bob']>View Bobs Account</a>

A plunk for this is here; https://plnkr.co/edit/BYKMucE3Y75uJSpV5VWx?p=preview

Click on "John" and "Dynamic Router Link Name = " and "John" should both be active. This sometimes work on the first click, if so, then click back to "Home", the click again on "John", you'll see only the hardcoded link is registered as active, even though the hrefs are identical.

Is this designed/impossible? or am i setting something incorrectly?

ct5845
  • 1,428
  • 3
  • 16
  • 20

6 Answers6

29

In your component:

import {Router} from '@angular/router';

isActive(instruction: any[]): boolean {
  // Set the second parameter to true if you want to require an exact match.
  return this.router.isActive(this.router.createUrlTree(instruction), false);
}

In your HTML:

<a [class.active]="isActive(['user', currentUser.name])">

Router.isActive() documentation on angular.io

bwegs
  • 3,769
  • 2
  • 30
  • 33
Victor Bredihin
  • 2,220
  • 21
  • 30
5

Accepted answer didn't work for me and I just wanted to highlight top level route matches so I used:

isActive(url): boolean {
    return this.router.url.includes(url);
}

and:

[class.active]="isActive('url')"
Tanya Branagan
  • 551
  • 1
  • 12
  • 21
2

routerLinkActive is evaluated on initial load and only when route is changed. It is no re-evaluated when the link is changed. Hence, dynamically generated link do not work with routerLinkActive. Victor Bredihin's solution above works as the component function is evaluated during rendering.

2

I found that the following work-around also works for my code:

<a [routerLink]=['user', currentUser.name]
   [routerLinkActive]='"active dummyclassname-" + currentUser.name'>
   {{currentUser.name}}
</a>

I.e. tricking Angular in revalidating 'routerLinkActive'.

1

Change your html as below :

<a [routerLink]=['user', currentUser.name] 
  routerLinkActive='active'>
    {{currentUser.name}}
</a>

You can also check Why Angular2 routerLinkActive sets active class to multiple links?

Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
ranakrunal9
  • 13,320
  • 3
  • 42
  • 43
  • routerLinkActive vs [routerLinkActive] doesnt seem to have any impact on the outcome. Also wasn't worried about multiple links being active, that's fine in this case, they should both be active, rather than just one. – ct5845 Sep 01 '16 at 12:43
  • Actually [routerLinkActive] is not correct way, it will work but throw error some time. – ranakrunal9 Sep 01 '16 at 12:47
1

You can apply an option for ancestors of linked elements

[routerLinkActiveOptions]="{exact: true}"