1

I have an app build with Angular 8. Routerlinkactive is not activated on dynamically generated route at the beginning, but when I click on some other links in the same module and come back then it works. The routerLinkActive is set in the UserComponent, and it should activate the anchor in navigation when the child (UserProfileComponent) is loaded based on url params.

enter image description here

I tried many solutions such as usage of template variable, for example

[routerLinkActive]="['']" [ngClass]="rla.isActive ? 'mat-accent' : 'mat-primary'" #rla="routerLinkActive" or applied [routerLinkActiveOptions]="{exact:true}" but none of them were helpfull.

This is last version of my HTML code.

<ul role="list"  class="list-horizontal">
  <li>
    <a class="mat-primary"
      routerLinkActive="mat-accent"
      [routerLink]="'/user/profile/' + profile?._id"
      mat-raised-button>Profile </a>
  </li>
  <li>
    <a class="mat-primary"
      [routerLink]="'/user/posts/'"
      [routerLinkActive]="['mat-accent']"
      mat-raised-button>Posts</a>
  </li>
  <li>
    <a class="mat-primary"
      [routerLink]="'/user/favorite-posts/'"
      [routerLinkActive]="['mat-accent']"
      mat-raised-button>Favourites</a>
  </li>
</ul>

I guess the problem is in dynamically generated route ( which is based on user id ),

For example http://my-domain/user/profile/5dd58c41409cccea2c9296f3 because when I access other components directly, for instance http://my-domain/user/posts then routerLinkActive works fine sets active class to the corresponding link. This is how my routes are configured for current module.

const routes: Routes = [{
    path: '',
    component: UserComponent,
    children: [
      {
        path: 'profile/:id',
        component: UserProfileComponent
      },
      {
        path: 'posts',
        component: UserPostsComponent
      },
      {
        path: 'favorite-posts',
        component: UserFavoritePostsComponent
      }
    ]
}];

Any hint is appreciated. Thanks!

johannesMatevosyan
  • 1,974
  • 2
  • 30
  • 40
  • 1
    try to define `userLink` as something like this: `[routerLink]="['user', 'profile', profile._id"` – akkonrad Dec 09 '19 at 09:43
  • actually Itried this option, but I guess url params usually are loaded a bit late therefore request goes with 'null' value in the end of url. – johannesMatevosyan Dec 09 '19 at 09:55
  • yes, it might be that, so you maybe add *ngIf on the li element to check weather profile is already loaded? – akkonrad Dec 09 '19 at 09:59

1 Answers1

0

I found another method to solve this problem, since I could not display active route with dynamically generated parameters. Therefore I am posting my answer so it might help others.

I decided to set mat-accent (active) class on selected element and remove that class from sibling elements. The trick is done with the help of ngClass directive.

Here is my updated HTML. (routerLinkActive property is not needed any more)

<ul role="list"  class="list-horizontal mb-15">
  <li>
    <a
      class="mat-primary"
      routerLinkActive="mat-accent"
      [routerLink]="'/user/profile/' + profile?._id"
      [ngClass]="{'mat-accent': selectedItem == 'profile'}"
      (click)="onSetActiveClass($event, 'profile')"
      mat-raised-button>Profile </a>
  </li>
  <li>
    <a
      class="mat-primary"
      [routerLink]="'/user/posts/' + profile?._id"
      [ngClass]="{'mat-accent': selectedItem == 'posts'}"
      (click)="onSetActiveClass($event, 'posts')"
      mat-raised-button>Posts</a>
  </li>
  <li>
    <a
      class="mat-primary"
      [routerLink]="'/user/favorite-posts/'"
      [ngClass]="{'mat-accent': selectedItem == 'favorite-posts'}"
      (click)="onSetActiveClass($event, 'favorite-posts')"
      mat-raised-button>Favourites</a>
  </li>
</ul>

And in typescript file:

ngOnInit() {
   this.onSetActiveClass(event, 'profile'); // pass the 'active' class on load
}

onSetActiveClass(event, newClass) {
        this.selectedItem = newClass;
}

Here is the source. Good luck! :)

johannesMatevosyan
  • 1,974
  • 2
  • 30
  • 40