Skip to content

Commit 5794401

Browse files
committed
fix(router): make currentSnapshot required in CanMatchFn (angular#67452)
it was only optional to avoid a breaking change in a minor BREAKING CHANGE: The `currentSnapshot` parameter in `CanMatchFn` and the `canMatch` method of the `CanMatch` interface is now required. While this was already the behavior of the Router at runtime, existing class implementations of `CanMatch` must now include the third argument to satisfy the interface. PR Close angular#67452
1 parent 7f94502 commit 5794401

4 files changed

Lines changed: 22 additions & 10 deletions

File tree

adev/src/content/guide/routing/route-guards.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,16 @@ It has access to the following default arguments:
125125

126126
- `route`: `Route` - The route configuration being evaluated
127127
- `segments`: `UrlSegment[]` - The URL segments that have not been consumed by previous parent route evaluations
128+
- `currentSnapshot: PartialMatchRouteSnapshot` - The current route snapshot up to this point in the matching process
128129

129130
It can return the [standard return guard types](#route-guard-return-types), but when it returns `false`, Angular tries other matching routes instead of completely blocking navigation.
130131

131132
```ts
132-
export const featureToggleGuard: CanMatchFn = (route: Route, segments: UrlSegment[]) => {
133+
export const featureToggleGuard: CanMatchFn = (
134+
route: Route,
135+
segments: UrlSegment[],
136+
currentSnapshot: PartialMatchRouteSnapshot,
137+
) => {
133138
const featureService = inject(FeatureService);
134139
return featureService.isFeatureEnabled('newDashboard');
135140
};

goldens/public-api/router/index.api.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,11 @@ export type CanLoadFn = (route: Route, segments: UrlSegment[]) => MaybeAsync<Gua
149149
// @public
150150
export interface CanMatch {
151151
// (undocumented)
152-
canMatch(route: Route, segments: UrlSegment[], currentSnapshot?: PartialMatchRouteSnapshot): MaybeAsync<GuardResult>;
152+
canMatch(route: Route, segments: UrlSegment[], currentSnapshot: PartialMatchRouteSnapshot): MaybeAsync<GuardResult>;
153153
}
154154

155155
// @public
156-
export type CanMatchFn = (route: Route, segments: UrlSegment[], currentSnapshot?: PartialMatchRouteSnapshot) => MaybeAsync<GuardResult>;
156+
export type CanMatchFn = (route: Route, segments: UrlSegment[], currentSnapshot: PartialMatchRouteSnapshot) => MaybeAsync<GuardResult>;
157157

158158
// @public
159159
export class ChildActivationEnd {

packages/examples/router/route_functional_guards.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
CanActivateChildFn,
1515
CanActivateFn,
1616
CanMatchFn,
17+
PartialMatchRouteSnapshot,
1718
provideRouter,
1819
ResolveFn,
1920
Route,
@@ -111,7 +112,11 @@ bootstrapApplication(App, {
111112
// #enddocregion
112113

113114
// #docregion CanMatchFn
114-
const canMatchTeam: CanMatchFn = (route: Route, segments: UrlSegment[]) => {
115+
const canMatchTeam: CanMatchFn = (
116+
route: Route,
117+
segments: UrlSegment[],
118+
currentSnapshot: PartialMatchRouteSnapshot,
119+
) => {
115120
return inject(PermissionsService).canMatch(inject(UserToken));
116121
};
117122

packages/router/src/models.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,7 +1113,11 @@ export type CanDeactivateFn<T> = (
11131113
* class CanMatchTeamSection implements CanMatch {
11141114
* constructor(private permissions: Permissions, private currentUser: UserToken) {}
11151115
*
1116-
* canMatch(route: Route, segments: UrlSegment[]): Observable<boolean>|Promise<boolean>|boolean {
1116+
* canMatch(
1117+
* route: Route,
1118+
* segments: UrlSegment[],
1119+
* currentSnapshot: PartialMatchRouteSnapshot,
1120+
* ): Observable<boolean> | Promise<boolean> | boolean {
11171121
* return this.permissions.canAccess(this.currentUser, route, segments);
11181122
* }
11191123
* }
@@ -1154,7 +1158,7 @@ export interface CanMatch {
11541158
canMatch(
11551159
route: Route,
11561160
segments: UrlSegment[],
1157-
currentSnapshot?: PartialMatchRouteSnapshot,
1161+
currentSnapshot: PartialMatchRouteSnapshot,
11581162
): MaybeAsync<GuardResult>;
11591163
}
11601164

@@ -1172,9 +1176,7 @@ export interface CanMatch {
11721176
*
11731177
* @param route The route configuration.
11741178
* @param segments The URL segments that have not been consumed by previous parent route evaluations.
1175-
* @param currentSnapshot The current route snapshot up to this point in the matching process. While this parameter is optional,
1176-
* it will always be defined when called by the Router. It is only optional for backwards compatibility with functions defined prior
1177-
* to the introduction of this parameter.
1179+
* @param currentSnapshot The current route snapshot up to this point in the matching process.
11781180
*
11791181
* @publicApi
11801182
* @see {@link Route}
@@ -1183,7 +1185,7 @@ export interface CanMatch {
11831185
export type CanMatchFn = (
11841186
route: Route,
11851187
segments: UrlSegment[],
1186-
currentSnapshot?: PartialMatchRouteSnapshot,
1188+
currentSnapshot: PartialMatchRouteSnapshot,
11871189
) => MaybeAsync<GuardResult>;
11881190

11891191
/**

0 commit comments

Comments
 (0)