Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Navigation ID is not equal to the current router navigation id error

I'm using @ngrx/router-store in my Angularv5 app and I recently started running into a an error: Navigation ID X is not equal to the current navigation id Y (where X and Y are integers).

This problem happens consistently when I navigate to route A from a specific route B. Navigating to route A from any other route seems to work fine.

The only other S.O. issue related to this which I've found, offers up the possibility that the issue could be caused by rapidly updating the navigation multiple times. To test if this was happening (it shouldn't be), I subscribed to router navigation events inside my root component, set a breakpoint inside the subscription, and opened up a debug session to step through the problem. Doing this, I can see that

  1. Say the current navigation ID is 11. When I navigate to the problem route, the router starts navigation, successfully executes every navigation event including NavigationEnd and then immediately @ngrx/router-store throws an 'ROUTER_CANCEL' action stating that: Navigation ID 12 is not equal to the current navigation id 13. As far as I can tell, 12 is the correct navigation ID (again, navigation ID 11 completes and immediately 'ROUTER_CANCEL' is thrown without the router emitting any further navigation events). Furthermore, the 'ROUTER_CANCEL' action payload contains both the router navigation event that caused the problem, as well as the state of the store when the problem was caused. The event which caused the problem has an ID of 12, the router state in the store at the time had an ID of 11. So again, 12 seems to be the correct navigation ID and should not be throwing an error.

  2. On navigation to the user profile route from a problem route, no other navigation occurs until @ngrx/router-store cancels navigation. (i.e. I am not rapidly updating the navigation route)

  3. Other than ngrx dispatching a 'ROUTER_CANCEL' action, no errors are reported (and no errors are thrown).

Again, the route experiencing problems works fine unless navigation begins from a specific route B. As far as I can tell, there is nothing different or unusual about this specific route B (nor does the problem route A care where people are coming from--the two routes have no association with each other).

One last thing: triggering the bug outside of a debug session always seems to cause errors in the form Navigation ID X is not equal to the current navigation id X+1, however triggering the bug inside a debug session might cause Navigation ID 11 is not equal to the current navigation id 15 or Navigation ID 13 is not equal to the current navigation id 20, etc.

Does anyone have any ideas what is going on? I'm not familiar enough with @ngrx/router-store to really guess how this might be happening. My assumption is that the navigation ID value in the store increases synchronously when NavigationEnd events are received by @ngrx/router-store, so I'm not even sure how the ids could ever get out of order---let alone in this case where the ids appear to be correct.

Any thoughts are greatly appreciated!

PS: I'm happy to post code, but my app is large and I don't have any clues as to where this bug is being triggered from.

like image 602
John Avatar asked May 13 '18 13:05

John


4 Answers

I figured it out! There was code in a component that was calling router.navigate() on a NavigationEnd event. So the answer was similar to the answer in this S.O. issue (rapidly changing the route).

I got this error because I was calling router.navigate twice in quick succession, (1 to append queryParams, 1 to append a fragment) so had to refactor my code to only call navigate once.

like image 130
John Avatar answered Nov 09 '22 23:11

John


Will post an answer, because I ran into similar issue, but it was hard to find why it happened. Hope it will help others ending up here...

When having this problem it can also be caused by a call to reset query params. For example in a ngOnDestroy method call:

public ngOnDestroy(): void {
  // Removing query params on destroy:
  this.router.navigate([], {
    relativeTo: this.route,
    queryParams: {},
    queryParamsHandling: 'merge',
    replaceUrl: true,
  });
}

In the method any query params present in the route are removed in the ngOnDestroy method of a component. Because of this method the route changes rapidly as well similar to @John mentions in his answer. It leads to the same problem: NavigationCancel event is fired with following message:

NavigationCancel {id: x, url: "/parent/child", reason: "Navigation ID x is not equal to the current navigation id x+1"}
  id: x
  url: "/parent/child"
  reason: "Navigation ID x is not equal to the current navigation id x+1"

And as a result NavigationEnd will never fire.


Note: You can enable tracing in your router config ExtraOptions with the param enableTracing set to true to make it easier to debug this issue.

like image 32
Wilt Avatar answered Nov 09 '22 22:11

Wilt


In my case I was just navigating inside component's constructor. Don't do that. It cancels the current navigation because it's not finished yet. Navigate inside ngOnInit because there the navigation is finished and you're free to navigate somewhere else.

like image 41
epsilon Avatar answered Nov 09 '22 23:11

epsilon


I had the exact same problem, but found another cause to explain it.


TL;DR

So this DOES NO WORK :

<a (click)="navigateTest()" href="#">click me</a>

Whereas THIS WORKS!

<a (click)="navigateTest()">click me</a>

Detailed answer

In my template

<a (click)="navigateTest()" href="#">click me</a>

In my Component

public navigateTest(): void {
    this.router.navigate(['/my-destination']);
}

First I activated the router debug tracing (enableTracing: true in router forRoot definition)

@NgModule({
  imports: [
    RouterModule.forRoot(routes, {useHash: true, enableTracing: true})
  ],
  exports: [RouterModule]
})
export class AppRoutingModule {
}

I saw that I had a NavigationStart event with id: 2, url: '/my-destination' navigationTrigger: 'imperative'

Then I have another NavigationStart event with id: 3, url: '/' navigationTrigger: 'popstate'

This one is not expected!

Sometimes (not always), I also have a NavigationCancelled event for id:2 between them, with cause Navigation ID 2 is not equal to the current navigation id 3

After hours of debug I found that this is because of the href="#" on the HTML a element on my template...

like image 2
TooLiPHoNe.NeT Avatar answered Nov 09 '22 21:11

TooLiPHoNe.NeT