1

I have some link like this

<li routerLinkActive="active" class="nav-item">
<a [routerLink]="['contracts']" 
[queryParams]="{ activeOnly: false }" 
class="nav-link">Contracts</a>
</li>

You see here in params i have ?activeOnly=false with this approach all is ok when my url is like

contracts?activeOnly=false active css class is added in html and user can see that it is active link

The problem I have that sometimes url can be changed like this contracts?activeOnly=true&id=1 then active css does not apply anymore.

What i need is to have active css class on element even if url has changed with query params.

Example if url is like this contracts?activeOnly=true&id=1

active css class must also stay on LI html tag

Piyush Jain
  • 1,895
  • 3
  • 19
  • 40
Miomir Dancevic
  • 6,726
  • 15
  • 74
  • 142

3 Answers3

6
Path: '/' Component: HomeComponent
Path: '/server' Component: ServerComponent
Path: '/about' Component: AboutComponent

HOME SERVER ABOUT

Default home will be selected, now if you navigate to server

HOME SERVER ABOUT

Both HOME and SERVER will become active

WHY?

Because in localhost:4200/server there is an empty path between localhost:4200 and server and that is / that will keep home tab also active.

Therefore in order to deal with it you use [routerLinkActiveOptions]="{exact : true}" with home tab. Now if you navigate to server, only server tab will be highlighted

Muhammad Bilal
  • 1,840
  • 1
  • 18
  • 16
  • 3
    I found that it worked when I used the new options: [routerLinkActiveOptions]="{ matrixParams: 'exact', queryParams: 'exact', paths: 'exact', fragment: 'exact' }" – Tayamba Mwanza Jun 20 '21 at 21:23
1

RouterLinkActive if used with queryParams needs to be an exact match, So the above solution will not work. There was a proposal to make routeLinkActiveOptions but was dropped by Angular team.

You can define your own method to identify active.

Here in the below snippet I am defining a method is link active will return true if the path url minus any query params matches the routerlink path passed from template.

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

constructor(private router: Router){

}

isLinkActive(link) {
  const url = this.router.url;
  return link.id === url.substring(1, url.indexOf('?'));
}

From the template assign class="active" if the method isLinkActive returns true

<li *ngFor="let link of links" [class.active]="isLinkActive(link)">
  <a [routerLink]="'/'+link.id" [queryParams]="{ activeOnly: false }">{{link.name}}</a>
</li>

Stackblitz : https://stackblitz.com/edit/angular-8f7jk8

joyBlanks
  • 6,419
  • 1
  • 22
  • 47
1

For anyone coming here as I did today, Angular (in March 2021) have resolved the issue of routerLinkActive for queryParams, more info can be found here...

Angular - routerLinkActive and queryParams handling

<div routerLinkActive="active-link" [routerLinkActiveOptions]="options">
</div>

Where options will have the either the shape of IsActiveMatchOptions

export declare interface IsActiveMatchOptions {
    fragment: 'exact' | 'ignored';
    matrixParams: 'exact' | 'subset' | 'ignored';
    paths: 'exact' | 'subset';
    queryParams: 'exact' | 'subset' | 'ignored';
}

or simply accept a boolean exact

{
   exact: boolean
}
Nikolaos
  • 29
  • 6
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/late-answers/32344639) – ahuemmer Aug 02 '22 at 06:26
  • Hey @ahuemmer, Good point, my response updated accordingly here – Nikolaos Aug 03 '22 at 07:14