-
Notifications
You must be signed in to change notification settings - Fork 25.3k
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
setUpLocationSync causes an duplicate navigation events #21610
Comments
I believe I am encountering a related issue where my call to My current workaround is to use |
It is hard to investigate without a reproduction. @bourey, could you create a (preferably minimal 😁) reproduction; either as a repo or a live demo? I wonder if this is related to #20244 at all. @jasonaden, you marked it as a regression. Is there any previous version that is known to work? |
@gkalpak It took me about 2 hours to get a concise reproduction but you can see the issue that I'm experiencing in this stackblitz. My example is complicated by some special bootstrapping but I believe the issue should be clearly demonstrated. https://stackblitz.com/edit/ajc-angular-upgrade-locationsync-bug I also tested my stackblitz with Angular versions 4.4.6 and 4.0.3 and the issue remained. |
@gkalpak We thought it was a regression, but as it turns out it had previously been broken. Changing the label. |
Also, this fix (#21728) went in so we can make a change such as this to
We are currently testing this change internally to make sure it doesn't open up other issues. |
I tried the change mentioned by @jasonaden but it didn't work. My 'fix' was to wrap my call to The problem I faced was if a trailing slash was included in an Angular route and it is the initial route, the listener registered by the sync would lead AngularJS to inform Angular of the route for a second time. Angular would start navigation having stripped the slash, but when the 'duplicate' came in via AngularJS, with the trailing slash intact, the original (correct) Angular route would be cancelled, replaced with duplicate. This meant instead of my route for |
In addtion to my previous work around, I am now ALSO using the |
For us, in some cases, it was affecting the browser's back button getting stuck in a loop of two pages The fix @jasonaden mentioned didn't work for me because Note: I'm using the last version of https://github.com/angular/angular/blob/7.0.x/packages/router/upgrade/src/upgrade.ts (that's where the
|
All the comments on here have been extremely helpful. Thanks to everyone who has participated. I also needed to do the It seems like @jasonaden said that he was going to get that into the codebase. But it's still not in. Any ideas on when this change might be made? I understand the push for Ivy. So I am simply looking for a timeline. Never is an acceptable answer, as well. |
There are no immediate plans to work on this afaik, but if anyone wants to submit a PR, I would be happy to review 😉 |
@aaronfrost @gkalpak Interesting, I have a scenario that's still not working when using skipLocationChange: true. Here's a stackblitz for my scenario: https://angular-4hte4b.stackblitz.io/#/ng2 If you open this link, click "AngularJS" and hit the browsers back button you will see it won't work until u click it twice. Did you manage to also resolve that specific scenario? If yes, any chance you could share how? Thanks! |
… Router This code mimics behavior that Google Analytics has been using to prevent duplicate navigations. They set up their own `HybridRoutingService` location sync to avoid duplicate navigations that came from the Angular router. This would happen because the Angular router would trigger a navigation, which would then get picked up by the `$locationShim`, which would trigger a `$locationChangeStart`, which would then be picked up by the `setUpLocationSync` watcher here, which would again trigger a navigation in the Angular Router. All of this can be prevented by checking if the `navigationId` exists on the history state object. This property is added by the Angular router during navigations. fixes angular#21610
… Router This code mimics behavior that Google Analytics has been using to prevent duplicate navigations. They set up their own `HybridRoutingService` location sync to avoid duplicate navigations that came from the Angular router. This would happen because the Angular router would trigger a navigation, which would then get picked up by the `$locationShim`, which would trigger a `$locationChangeStart`, which would then be picked up by the `setUpLocationSync` watcher here, which would again trigger a navigation in the Angular Router. All of this can be prevented by checking if the `navigationId` exists on the history state object. This property is added by the Angular router during navigations. fixes angular#21610
… Router This code mimics behavior that Google Analytics has been using to prevent duplicate navigations. They set up their own `HybridRoutingService` location sync to avoid duplicate navigations that came from the Angular router. This would happen because the Angular router would trigger a navigation, which would then get picked up by the `$locationShim`, which would trigger a `$locationChangeStart`, which would then be picked up by the `setUpLocationSync` watcher here, which would again trigger a navigation in the Angular Router. All of this can be prevented by checking if the `navigationId` exists on the history state object. This property is added by the Angular router during navigations. fixes angular#21610
… Router This code mimics behavior that Google Analytics has been using to prevent duplicate navigations. They set up their own `HybridRoutingService` location sync to avoid duplicate navigations that came from the Angular router. This would happen because the Angular router would trigger a navigation, which would then get picked up by the `$locationShim`, which would trigger a `$locationChangeStart`, which would then be picked up by the `setUpLocationSync` watcher here, which would again trigger a navigation in the Angular Router. All of this can be prevented by checking if the `navigationId` exists on the history state object. This property is added by the Angular router during navigations. fixes angular#21610
… Router This code mimics behavior that Google Analytics has been using to prevent duplicate navigations. They set up their own `HybridRoutingService` location sync to avoid duplicate navigations that came from the Angular router. This would happen because the Angular router would trigger a navigation, which would then get picked up by the `$locationShim`, which would trigger a `$locationChangeStart`, which would then be picked up by the `setUpLocationSync` watcher here, which would again trigger a navigation in the Angular Router. All of this can be prevented by checking if the `navigationId` exists on the history state object. This property is added by the Angular router during navigations. fixes angular#21610
… Router This code mimics behavior that Google Analytics has been using to prevent duplicate navigations. They set up their own `HybridRoutingService` location sync to avoid duplicate navigations that came from the Angular router. This would happen because the Angular router would trigger a navigation, which would then get picked up by the `$locationShim`, which would trigger a `$locationChangeStart`, which would then be picked up by the `setUpLocationSync` watcher here, which would again trigger a navigation in the Angular Router. All of this can be prevented by checking if the `navigationId` exists on the history state object. This property is added by the Angular router during navigations. fixes angular#21610
… Router This code mimics behavior that Google Analytics has been using to prevent duplicate navigations. They set up their own `HybridRoutingService` location sync to avoid duplicate navigations that came from the Angular router. This would happen because the Angular router would trigger a navigation, which would then get picked up by the `$locationShim`, which would trigger a `$locationChangeStart`, which would then be picked up by the `setUpLocationSync` watcher here, which would again trigger a navigation in the Angular Router. All of this can be prevented by checking if the `navigationId` exists on the history state object. This property is added by the Angular router during navigations. fixes angular#21610
… Router This code mimics behavior that Google Analytics has been using to prevent duplicate navigations. They set up their own `HybridRoutingService` location sync to avoid duplicate navigations that came from the Angular router. This would happen because the Angular router would trigger a navigation, which would then get picked up by the `$locationShim`, which would trigger a `$locationChangeStart`, which would then be picked up by the `setUpLocationSync` watcher here, which would again trigger a navigation in the Angular Router. All of this can be prevented by checking if the `navigationId` exists on the history state object. This property is added by the Angular router during navigations. fixes angular#21610
… Router This code mimics behavior that Google Analytics has been using to prevent duplicate navigations. They set up their own `HybridRoutingService` location sync to avoid duplicate navigations that came from the Angular router. This would happen because the Angular router would trigger a navigation, which would then get picked up by the `$locationShim`, which would trigger a `$locationChangeStart`, which would then be picked up by the `setUpLocationSync` watcher here, which would again trigger a navigation in the Angular Router. All of this can be prevented by checking if the `navigationId` exists on the history state object. This property is added by the Angular router during navigations. fixes angular#21610
… Router This code mimics behavior that Google Analytics has been using to prevent duplicate navigations. They set up their own `HybridRoutingService` location sync to avoid duplicate navigations that came from the Angular router. This would happen because the Angular router would trigger a navigation, which would then get picked up by the `$locationShim`, which would trigger a `$locationChangeStart`, which would then be picked up by the `setUpLocationSync` watcher here, which would again trigger a navigation in the Angular Router. All of this can be prevented by checking if the `navigationId` exists on the history state object. This property is added by the Angular router during navigations. fixes angular#21610
… Router (#43441) This code mimics behavior that Google Analytics has been using to prevent duplicate navigations. They set up their own `HybridRoutingService` location sync to avoid duplicate navigations that came from the Angular router. This would happen because the Angular router would trigger a navigation, which would then get picked up by the `$locationShim`, which would trigger a `$locationChangeStart`, which would then be picked up by the `setUpLocationSync` watcher here, which would again trigger a navigation in the Angular Router. All of this can be prevented by checking if the `navigationId` exists on the history state object. This property is added by the Angular router during navigations. fixes #21610 PR Close #43441
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Angular's router upgrade code provides a setUpLocationSync method which listens for AngularJS-initiated $locationChangeStart events, then calls Angular's router.navigateByUrl. The docs for this method state that "History.pushState does not fire onPopState, so the Angular location doesn't detect it. The workaround is to attach a location change listener"(
angular/packages/router/upgrade/src/upgrade.ts
Line 55 in e4c53f8
While this code works for AngularJS-initiated location changes, it currently produces duplicate NavigationStart, etc. events for Angular-initiated changes. The AngularJS router sees that the browser location has changed and triggers a location change event, which in turn triggers an additional NavigationStart event in Angular. It appears that we need some way to trigger Angular navigation only for location changes that originate in AngularJS.
This issue is currently causing duplicate router events for any Angular-driven page transition in dual-router apps, which is a performance issue.
The text was updated successfully, but these errors were encountered: