mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
8735af08b9
Returning `UrlTree` from a guard was a convenient new feature added to the `Router`. However, it does not have feature-parity with the old `router.navigate(...); return false;` pattern. The most common use-case for this feature is to redirect to a new page _without_ updating the URL from the initially attempted navigation. For example, rendering a 404 page when the user does not have access privelages to a route. Fixes #17004 Fixes #27148 BREAKING CHANGE: Guards can now return `RedirectCommand` for redirects in addition to `UrlTree`. Code which expects only `boolean` or `UrlTree` values in `Route` types will need to be adjusted. PR Close #45023
63 lines
2.2 KiB
TypeScript
63 lines
2.2 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google LLC All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
|
|
import {NavigationCancellationCode} from './events';
|
|
import {NavigationBehaviorOptions, RedirectCommand} from './models';
|
|
import {isUrlTree, UrlSerializer, UrlTree} from './url_tree';
|
|
|
|
export const NAVIGATION_CANCELING_ERROR = 'ngNavigationCancelingError';
|
|
|
|
export type NavigationCancelingError = Error & {
|
|
[NAVIGATION_CANCELING_ERROR]: true;
|
|
cancellationCode: NavigationCancellationCode;
|
|
};
|
|
export type RedirectingNavigationCancelingError = NavigationCancelingError & {
|
|
url: UrlTree;
|
|
navigationBehaviorOptions?: NavigationBehaviorOptions;
|
|
cancellationCode: NavigationCancellationCode.Redirect;
|
|
};
|
|
|
|
export function redirectingNavigationError(
|
|
urlSerializer: UrlSerializer,
|
|
redirect: UrlTree | RedirectCommand,
|
|
): RedirectingNavigationCancelingError {
|
|
const {redirectTo, navigationBehaviorOptions} = isUrlTree(redirect)
|
|
? {redirectTo: redirect, navigationBehaviorOptions: undefined}
|
|
: redirect;
|
|
const error = navigationCancelingError(
|
|
ngDevMode && `Redirecting to "${urlSerializer.serialize(redirectTo)}"`,
|
|
NavigationCancellationCode.Redirect,
|
|
) as RedirectingNavigationCancelingError;
|
|
error.url = redirectTo;
|
|
error.navigationBehaviorOptions = navigationBehaviorOptions;
|
|
return error;
|
|
}
|
|
|
|
export function navigationCancelingError(
|
|
message: string | null | false,
|
|
code: NavigationCancellationCode,
|
|
) {
|
|
const error = new Error(`NavigationCancelingError: ${message || ''}`) as NavigationCancelingError;
|
|
error[NAVIGATION_CANCELING_ERROR] = true;
|
|
error.cancellationCode = code;
|
|
return error;
|
|
}
|
|
|
|
export function isRedirectingNavigationCancelingError(
|
|
error: unknown | RedirectingNavigationCancelingError,
|
|
): error is RedirectingNavigationCancelingError {
|
|
return (
|
|
isNavigationCancelingError(error) &&
|
|
isUrlTree((error as RedirectingNavigationCancelingError).url)
|
|
);
|
|
}
|
|
|
|
export function isNavigationCancelingError(error: unknown): error is NavigationCancelingError {
|
|
return !!error && (error as NavigationCancelingError)[NAVIGATION_CANCELING_ERROR];
|
|
}
|