From 5128ba036ae4a02a2d7d54ace635245bda631a75 Mon Sep 17 00:00:00 2001 From: Andrew Scott Date: Tue, 10 Jan 2023 10:40:49 -0800 Subject: [PATCH] refactor(router): Warn if a navigation will change in the upcoming v16 release (#48688) v16 will have a breaking change to the way `UrlTree`s are constructed. This change is actually a bug fix that makes `UrlTree` creation correct in more scenarios (see #48508). However, this can affect applications that are relying on the current incorrect behavior. This commit adds a dev mode warning when the target of a navigation will change once #48508 is submitted. PR Close #48688 --- .../bundling/router/bundle.golden_symbols.json | 3 +++ packages/router/src/create_url_tree_strategy.ts | 15 ++++++++++++++- packages/router/src/router.ts | 12 ++++++++---- packages/router/src/url_tree.ts | 2 ++ 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/packages/core/test/bundling/router/bundle.golden_symbols.json b/packages/core/test/bundling/router/bundle.golden_symbols.json index 6f5f173119c..27c5ddc7c33 100644 --- a/packages/core/test/bundling/router/bundle.golden_symbols.json +++ b/packages/core/test/bundling/router/bundle.golden_symbols.json @@ -890,6 +890,9 @@ { "name": "createTemplateRef" }, + { + "name": "createUrlTree" + }, { "name": "deactivateRouteAndItsChildren" }, diff --git a/packages/router/src/create_url_tree_strategy.ts b/packages/router/src/create_url_tree_strategy.ts index acebc6a40ce..8629f3706cf 100644 --- a/packages/router/src/create_url_tree_strategy.ts +++ b/packages/router/src/create_url_tree_strategy.ts @@ -21,7 +21,20 @@ export class LegacyCreateUrlTree implements CreateUrlTreeStrategy { relativeTo: ActivatedRoute|null|undefined, currentState: RouterState, currentUrlTree: UrlTree, commands: any[], queryParams: Params|null, fragment: string|null): UrlTree { const a = relativeTo || currentState.root; - return createUrlTree(a, currentUrlTree, commands, queryParams, fragment); + const tree = createUrlTree(a, currentUrlTree, commands, queryParams, fragment); + if (NG_DEV_MODE) { + const treeFromSnapshotStrategy = new CreateUrlTreeUsingSnapshot().createUrlTree( + relativeTo, currentState, currentUrlTree, commands, queryParams, fragment); + if (treeFromSnapshotStrategy.toString() !== tree.toString()) { + let warningString = `The navigation to ${tree.toString()} will instead go to ${ + treeFromSnapshotStrategy.toString()} in an upcoming version of Angular.`; + if (!!relativeTo) { + warningString += ' `relativeTo` might need to be removed from the `UrlCreationOptions`.'; + } + tree._warnIfUsedForNavigation = warningString; + } + } + return tree; } } diff --git a/packages/router/src/router.ts b/packages/router/src/router.ts index 045326ec93a..fc3a4eca6e1 100644 --- a/packages/router/src/router.ts +++ b/packages/router/src/router.ts @@ -555,10 +555,14 @@ export class Router { navigateByUrl(url: string|UrlTree, extras: NavigationBehaviorOptions = { skipLocationChange: false }): Promise { - if (typeof ngDevMode === 'undefined' || - ngDevMode && this.isNgZoneEnabled && !NgZone.isInAngularZone()) { - this.console.warn( - `Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?`); + if (NG_DEV_MODE) { + if (this.isNgZoneEnabled && !NgZone.isInAngularZone()) { + this.console.warn( + `Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?`); + } + if (url instanceof UrlTree && url._warnIfUsedForNavigation) { + this.console.warn(url._warnIfUsedForNavigation); + } } const urlTree = isUrlTree(url) ? url : this.parseUrl(url); diff --git a/packages/router/src/url_tree.ts b/packages/router/src/url_tree.ts index 4052b5668e8..13f565bd9b5 100644 --- a/packages/router/src/url_tree.ts +++ b/packages/router/src/url_tree.ts @@ -190,6 +190,8 @@ function matrixParamsMatch( export class UrlTree { /** @internal */ _queryParamMap?: ParamMap; + /** @internal */ + _warnIfUsedForNavigation?: string; constructor( /** The root segment group of the URL tree */