A. Gladkiy
A. Gladkiy

Reputation: 3450

routerLinkActive for dynamic routes by default is active Angular 2

I have two links and url I get dynamically by ngOnInit.

<li><a [routerLink]="welcomeUrl" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">Getting Started</a></li>
<li><a [routerLink]="dashboardUrl" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">Dashboard</a></li>

Here is my component:

ngOnInit() {
        this.dataService.getOptions().subscribe((options: Options) => {
            if (options.mode.toLowerCase() === "live") {
                this.dashboardUrl = '/';
                this.welcomeUrl = 'welcome';
            } else {
                this.dataService.getName().subscribe((name: string) => {
                    this.dashboardUrl = name;
                    this.welcomeUrl = name + '/welcome';
                });
            }
        });
    }

And routes:

const routes: Routes = [
    { path: '', component: DashboardComponent },
    { path: 'welcome', loadChildren: 'app/welcome/welcome.module#WelcomeModule' },
    { path: ':name', component: DashboardComponent },
    { path: ':name/welcome', loadChildren: 'app/welcome/welcome.module#WelcomeModule' },
];

But when I launch app these links are active. They are starting to work fine after click on link that change url.

May be by default these links (urls) are empty and always active? How can I fix that?

Upvotes: 2

Views: 7048

Answers (2)

omar jaziri
omar jaziri

Reputation: 11

Try this:

<li>
  <a [routerLink]="dashboardUrl" routerLinkActive="active"
     [routerLinkActiveOptions]="{exact: true,__change_detection_hack__:dashboardUrl}">
    Dashboard
  </a>
</li>

this can help you: https://github.com/angular/angular/issues/18469

Upvotes: 1

AngularChef
AngularChef

Reputation: 14077

First of all, writing [routerLink] (with the [ ]) makes the directive expect an array, so your code should read:

<a [routerLink]="welcomeUrl" routerLinkActive="active">...</a>

But I think the problem is due to the async nature of your code: routerLinkActive executes before welcomeUrl is set and it can't do its job.

Solution #1: Wrap your links with *ngIf (quick & dirty)

Wrap your links with a test to only display them once the variables are set:

<ul *ngIf="welcomeUrl && dashboardUrl">
  <li><a [routerLink]="welcomeUrl" routerLinkActive="active">Getting Started</a></li>
  <li><a [routerLink]="dashboardUrl" routerLinkActive="active">Dashboard</a></li>
</ul>

Solution #2: Move the async call (more robust but more work)

Another option would be to move your async call — this.dataService.getOptions() — to a point that gets executed before the component containing the routerLinks gets activated.

It's hard to be more specific without knowing how your components are organized, but:

  • If the component containing the routerLinks is a routed component, you could add a resolve param to its route declaration and call this.dataService.getOptions() inside the resolve. The resolve would fetch the "mode" and then pass it to the component via ActivatedRoute.data["mode"]. See the documentation on Resolve: https://angular.io/docs/ts/latest/guide/router.html#resolve-guard
  • If the component containing the routerLinks is a child component of another component, you could call this.dataService.getOptions() inside the parent and pass the "mode" to the child via an @Input.

In both cases, the idea is the same: to figure out the "mode" before activating the component containing the routerLinks, so you can set the welcomeUrl and dashboardUrl variables before routerLinkActive is executed.

To test whether the async call is indeed the cause of you problem, try the *ngIf solution and see if it works.

Upvotes: 4

Related Questions