Reputation: 3450
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
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
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:
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-guardthis.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