Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[routerLink] with async/observable property assignment does not re-evaluate [routerLinkActive] when the observable emits a new value. #13865

Closed
josh-sachs opened this issue Jan 10, 2017 · 23 comments
Milestone

Comments

@josh-sachs
Copy link

josh-sachs commented Jan 10, 2017

I'm submitting a ... (check one with "x")

[x] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior

[routerLink] with async/observable property assignment does not re-evaluate [routerLinkActive] when the observable emits a new value.

Expected behavior

When the value emitted to [routerLink] changes, [routerLinkActive] should re-evaluate against the newly emitted value whether or not the link is "active."

Minimal reproduction of the problem with instructions

<a class="waves-effect" [routerLink]="observable$ | async" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{ exact: true }">LINK

the application of the "active" class will not be re-evaluated when a new value is emitted by observable$.
e.g.
obervable$ = Observable.interval(1000).map(i => ['/page/' + i])

If you are on /page/0 link will be active on first emission, but will not go inactive once i > 1.

What is the motivation / use case for changing the behavior?

Using observables with routerLink should work.

Please tell us about your environment:

Chrome 55m, Windows 10

  • Angular version: 2.0.X

2.4.1

  • Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
  • Language: [all | TypeScript X.X | ES6/7 | ES5]
    TypeScript 2.1.4.0

  • Node (for AoT issues): node --version =

@DzmitryShylovich
Copy link
Contributor

DzmitryShylovich commented Jan 10, 2017

Yeah, it's a known bug. RouterLinkActive is not updated when RouterLink input has changed.
Duplicate of #13075
But I would leave this one open and close #13075, because it has a better description.

@josh-sachs
Copy link
Author

Are you sure the two tickets are describing the same issue? This isn't an issue where 'active' isn't updated when the page route changes (which is what I understand from the other ticket) - this is an issue where you stay on the same page, but change the value of a link via an observable.

@DzmitryShylovich
Copy link
Contributor

Both issues have the same origin - RouterLinkActive.update() is not called when RouterLink input has changed. It's very hard to debug from #13075 (because it contains a lot of unrelated code), this is why I want to keep this issue opened instead of #13075

@bastienJS
Copy link

@DzmitryShylovich

That is my plunkr, it has unrelated code but you can repro the same buggy behavior:

https://plnkr.co/edit/C9W0pHvy27J83m25YUOJ?p=preview

These are the steps to retrace the problem:

  1. Open project 'neverending'
  2. the url shows /projects/1/tests then
  3. The 'Tests link' is orange highlighted
  4. change the route in the url bar to /projects/2/tests
  5. the formerly highlighted 'Tests link' is now NOT orange anymore.

@bastienJS
Copy link

Any news on this after 2 months? My application menu is still not yet activated :/

@josh-sachs
Copy link
Author

@bastienJS still not fixed. A work-around I'm using is to add a (click) event handler to invoke navigation within the navigation component... it sucks but it works. in the interim.

@bastienJS
Copy link

bastienJS commented Apr 5, 2017

@josh-sachs You want to tell me that within my component containing the brokenk Links I should do a router.navigate(...) to the url I am already on? Hm yeah loading data twice and its silly, but thanks for the workaround I will have to use it!

@netmikey
Copy link

netmikey commented Apr 6, 2017

The workaround doesn't work for me: I have a path like /{sectionId} and the section can be switched from multiple places within the application and the main menu link has to adapt to that. So the router link looks like [routerLink]="[myService.sectionIdObservable() | async]". I have a resolver that checks the sectionId from the path before activating the route and updates the global state if the sectionIds differ.

Everything works fine except for the routerLinkActive part.

@tytskyi
Copy link

tytskyi commented Apr 6, 2017

@netmikey i guess you are creating new observable on every change detection. Make sure it is single object.

Observe no function call
[routerLink]="[myService.sectionId$ | async]"

@josh-sachs
Copy link
Author

@bastienJS The workaround I proposed was to use (click) handler instead of [routerLink]. If you navigate to a url you are already on - nothing happens... no component is re-initialized.

<a href='javascript' (click)="Navigate('/some/url')" [class.active]="IsActive('/some/url')">Link</a>

@Component({...}) public class SomeComponent {
  constructor(private router: Router) { ... }
  public Navigate(location: string) { this.router.navigateByUrl(location); }
}

@bastienJS
Copy link

@josh-sachs Thanks now I understand it.

@netmikey
Copy link

netmikey commented May 3, 2017

Any news on this? It seems like this is still present in Angular 4.1.0.

@timvdalen
Copy link

I'm using the following workaround, based on the fact that the RouterLinkActiveOptions can also trigger updates:

<a [routerLink]="link" routerLinkActive="active" [routerLinkActiveOptions]="rlao">Link</a>

with:

this.rlao = {dummy: true};

Whenever the route changes (can be routing events):

this.rlao = {dummy: !this.rlao.dummy};

@ghost
Copy link

ghost commented Jun 15, 2017

@timvdalen Thank you, put an end to many hours of frustration. You can make the workaround less ugly by just re-assigning the actual setting you want this.rlao = { exact: false }; on route events (you don't need to flip dummy, new object is enough).

@bastienJS
Copy link

bastienJS commented Jun 26, 2017

Even renaming rlao to rlmao did not work :/

I just wanted to activate the link for test purpose for any event

this.router.events.subscribe(event => {
this.rlao = { exact: false };
}

What do I wrong? I hit F5 and the whole site reloads, but the current route in the browser does not trigger the RouterLink to be activated, only when I click it...

@dgroh
Copy link

dgroh commented Jul 12, 2017

I can confirm this bug.

My workaround was adding [class.active] directive.

<a routerLink="{{contract?.id}}/Customers" routerLinkActive="active" [class.active]="contract?.id">Customers</a>

@bastienJS
Copy link

Contrary to my previous statement the rlao trick does work! - in my plunker - just not in my local app on the computer. I moved now the plunkr piece by piece to my local app with a new angular cli setup project and it still works!!! Somehow my local app was broken but I could not find out why... I bet this bug will survive ng 5.1 :P it must be really lots of effort to fix this then...

@srowe0091
Copy link

Any news on this fix? i can't seem to get any of those workarounds to work for me

@miguelleite
Copy link

Any update on this? Is there an ETA for a fix?

@bastienJS
Copy link

Any update on this? Is there an ETA for a fix?

yes => NEVER :P

@atscott
Copy link
Contributor

atscott commented May 26, 2020

@atscott atscott added the router: directives RouterLink, RouterLinkActive, RouterOutlet etc. label May 26, 2020
@atscott
Copy link
Contributor

atscott commented May 27, 2020

Duplicate of #18469

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Jun 27, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests