Problem
NOTE: There are a lot of different answers here, and most of them have been correct at some point. The truth is that while the Angular team has modified its Router, what works has changed as well. Many of these methods are broken in the Router 3.0 version, which will eventually be the router in Angular, although it gives a very simple solution of its own. The preferred method, as stated in this answer, is to use [routerLinkActive] as of RC.3.
In an Angular application (current in the 2.0.0-beta.0 release as I write this), how do you determine what the currently active route is?
I’m working on an app that uses Bootstrap 4 and I need a way to mark navigation links/buttons as active when their associated component is being shown in a tag.
I recognize I could keep the state when one of the buttons is clicked, but that wouldn’t account for the case where there are numerous paths leading to the same destination (say a main navigation menu as well as a local menu in the main component).
Any links or suggestions would be greatly appreciated. Thanks.
Asked by Michael Oryl
Solution #1
With the new Angular router, you can add a [routerLinkActive]=”[‘your-class-name’]” attribute to all your links:
<a [routerLink]="['/home']" [routerLinkActive]="['is-active']">Home</a>
If only one class is required, use the non-array format:
<a [routerLink]="['/home']" [routerLinkActive]="'is-active'">Home</a>
If only one class is required, use the following format:
<a [routerLink]="['/home']" routerLinkActive="is-active">Home</a>
For more information, see the routerLinkActive directive, which is poorly documented. (I figured it out primarily via trial and error.)
UPDATE: The routerLinkActive directive now has better documentation, which you can find here. (In the comments below, thanks to @Victor Hugo Arango A.)
Answered by jessepinho
Solution #2
This is something I addressed in another question, but I believe it is applicable to this one as well. The original answer can be found here: Angular 2: How can I use parameters to identify which route is active?
I’ve been attempting to set the active class without knowing the precise location of the current location (using the route name). The best approach I’ve come up with thus far is to use the Router class’s isRouteActive function.
router.isRouteActive(instruction): Boolean takes a single parameter, a route Instruction object, and returns true or false depending on whether the instruction is true or false for the current route. Router’s generate command can be used to create a route instruction (linkParams: Array). Router.isRouteActive(router.generate([‘/User’, user: user.id ]) uses the same LinkParams format as a value supplied into a routerLink directive (e.g. router.isRouteActive(router.generate([‘/User’, user: user.id ])).
This is how the RouteConfig could look like (I’ve tweaked it a bit to show the usage of params):
@RouteConfig([
{ path: '/', component: HomePage, name: 'Home' },
{ path: '/signin', component: SignInPage, name: 'SignIn' },
{ path: '/profile/:username/feed', component: FeedPage, name: 'ProfileFeed' },
])
And the View would be as follows:
<li [class.active]="router.isRouteActive(router.generate(['/Home']))">
<a [routerLink]="['/Home']">Home</a>
</li>
<li [class.active]="router.isRouteActive(router.generate(['/SignIn']))">
<a [routerLink]="['/SignIn']">Sign In</a>
</li>
<li [class.active]="router.isRouteActive(router.generate(['/ProfileFeed', { username: user.username }]))">
<a [routerLink]="['/ProfileFeed', { username: user.username }]">Feed</a>
</li>
This has been my preferred solution for the problem so far, it might be helpful for you as well.
Answered by Alex Santos
Solution #3
Based on https://github.com/angular/angular/pull/6407#issuecomment-190179875, I made a small change to @alex-correia-santos’ answer.
import {Router, RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
// ...
export class App {
constructor(private router: Router) {
}
// ...
isActive(instruction: any[]): boolean {
return this.router.isRouteActive(this.router.generate(instruction));
}
}
And put it to use like this:
<ul class="nav navbar-nav">
<li [class.active]="isActive(['Home'])">
<a [routerLink]="['Home']">Home</a>
</li>
<li [class.active]="isActive(['About'])">
<a [routerLink]="['About']">About</a>
</li>
</ul>
Answered by tomaszbak
Solution #4
I found an easy answer for your query after solving a problem I faced in this link. In your styles, you might use router-link-active instead.
@Component({
styles: [`.router-link-active { background-color: red; }`]
})
export class NavComponent {
}
Answered by Quy Tang
Solution #5
By injecting the Location object into your controller and verifying path(), you can get the current route:
class MyController {
constructor(private location:Location) {}
... location.path(); ...
}
You’ll need to make certain that you import it first:
import {Location} from "angular2/router";
To determine which route is active, use a regular expression to match against the path that is returned. Regardless of which LocationStrategy you use, the Location class returns a normalized path. As a result, even if you use the HashLocationStratagegy, the paths provided will still be of the form /foo/bar. instead of #/foo/bar
Answered by Jason Teplitz
Post is based on https://stackoverflow.com/questions/34323480/in-angular-how-do-you-determine-the-active-route