fix(router): adjust UrlTree redirect to replace URL if in eager update (#31168)
Without this change when using UrlTree redirects in `urlUpdateStrategy="eager"`, the URL would get updated to the target location, then redirected. This resulted in having an additional entry in the `history` and thus the `back` button would be broken (going back would land on the URL causing a new redirect). Additionally, there was a bug where the redirect, even without `urlUpdateStrategy="eager"`, could create a history with too many entries. This was due to kicking off a new navigation within the navigation cancelling logic. With this PR the new navigation is pushed to the next tick with a `setTimeout`, allowing the page being redirected from to be cancelled before starting a new navigation. Related to #27148 PR Close #31168
This commit is contained in:

committed by
Alex Rickabaugh

parent
f96a81a818
commit
15e397816f
@ -2464,6 +2464,39 @@ describe('Integration', () => {
|
||||
[NavigationEnd, '/'],
|
||||
]);
|
||||
})));
|
||||
|
||||
it('replaces URL when URL is updated eagerly so back button can still work',
|
||||
fakeAsync(inject([Router, Location], (router: Router, location: SpyLocation) => {
|
||||
router.urlUpdateStrategy = 'eager';
|
||||
router.resetConfig([
|
||||
{path: '', component: SimpleCmp},
|
||||
{path: 'one', component: RouteCmp, canActivate: ['returnUrlTree']},
|
||||
{path: 'redirected', component: SimpleCmp}
|
||||
]);
|
||||
const fixture = createRoot(router, RootCmp);
|
||||
router.navigateByUrl('/one');
|
||||
|
||||
tick();
|
||||
|
||||
expect(location.path()).toEqual('/redirected');
|
||||
expect(location.urlChanges).toEqual(['replace: /', '/one', 'replace: /redirected']);
|
||||
})));
|
||||
|
||||
it('should resolve navigateByUrl promise after redirect finishes',
|
||||
fakeAsync(inject([Router, Location], (router: Router, location: SpyLocation) => {
|
||||
let resolvedPath = '';
|
||||
router.urlUpdateStrategy = 'eager';
|
||||
router.resetConfig([
|
||||
{path: '', component: SimpleCmp},
|
||||
{path: 'one', component: RouteCmp, canActivate: ['returnUrlTree']},
|
||||
{path: 'redirected', component: SimpleCmp}
|
||||
]);
|
||||
const fixture = createRoot(router, RootCmp);
|
||||
router.navigateByUrl('/one').then(v => { resolvedPath = location.path(); });
|
||||
|
||||
tick();
|
||||
expect(resolvedPath).toBe('/redirected');
|
||||
})));
|
||||
});
|
||||
|
||||
describe('runGuardsAndResolvers', () => {
|
||||
|
Reference in New Issue
Block a user