Skip to content

Commit 455c728

Browse files
atscottAndrewKushnir
authored andcommitted
feat(router): helper functions to convert class guards to functional (#48709)
This commit introduces helper functions to easily convert `Injectable`s with functions compatible with `Route` guards to the corresponding guard functions. These functions will serve to aid in migrating off of the now deprecated class-based guards, but also provide an easy avenue to still defining guards as `Injectable` classes if that is desired. PR Close #48709
1 parent 7e35a91 commit 455c728

File tree

5 files changed

+142
-3
lines changed

5 files changed

+142
-3
lines changed

goldens/public-api/router/index.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,31 @@ export type LoadChildren = LoadChildrenCallback;
371371
// @public
372372
export type LoadChildrenCallback = () => Type<any> | NgModuleFactory<any> | Routes | Observable<Type<any> | Routes | DefaultExport<Type<any>> | DefaultExport<Routes>> | Promise<NgModuleFactory<any> | Type<any> | Routes | DefaultExport<Type<any>> | DefaultExport<Routes>>;
373373

374+
// @public
375+
export function mapToCanActivate(providers: Array<Type<{
376+
canActivate: CanActivateFn;
377+
}>>): CanActivateFn[];
378+
379+
// @public
380+
export function mapToCanActivateChild(providers: Array<Type<{
381+
canActivateChild: CanActivateChildFn;
382+
}>>): CanActivateChildFn[];
383+
384+
// @public
385+
export function mapToCanDeactivate<T = unknown>(providers: Array<Type<{
386+
canDeactivate: CanDeactivateFn<T>;
387+
}>>): CanDeactivateFn<T>[];
388+
389+
// @public
390+
export function mapToCanMatch(providers: Array<Type<{
391+
canMatch: CanMatchFn;
392+
}>>): CanMatchFn[];
393+
394+
// @public
395+
export function mapToResolve<T>(provider: Type<{
396+
resolve: ResolveFn<T>;
397+
}>): ResolveFn<T>;
398+
374399
// @public
375400
export interface Navigation {
376401
extractedUrl: UrlTree;

packages/examples/router/BUILD.bazel

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@ ng_module(
1010
deps = [
1111
"//packages/core",
1212
"//packages/platform-browser",
13-
"//packages/platform-browser-dynamic",
1413
"//packages/router",
15-
"//packages/zone.js/lib",
16-
"@npm//rxjs",
1714
],
1815
)
1916

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {Injectable} from '@angular/core';
10+
import {mapToCanActivate, mapToResolve, Route} from '@angular/router';
11+
12+
// #docregion CanActivate
13+
@Injectable({providedIn: 'root'})
14+
export class AdminGuard {
15+
canActivate() {
16+
return true;
17+
}
18+
}
19+
20+
const route: Route = {
21+
path: 'admin',
22+
canActivate: mapToCanActivate([AdminGuard]),
23+
};
24+
// #enddocregion
25+
26+
// #docregion Resolve
27+
@Injectable({providedIn: 'root'})
28+
export class ResolveUser {
29+
resolve() {
30+
return {name: 'Bob'};
31+
}
32+
}
33+
34+
const userRoute: Route = {
35+
path: 'user',
36+
resolve: {
37+
user: mapToResolve(ResolveUser),
38+
},
39+
};
40+
// #enddocregion

packages/router/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export {ActivatedRoute, ActivatedRouteSnapshot, RouterState, RouterStateSnapshot
2727
export {convertToParamMap, defaultUrlMatcher, ParamMap, Params, PRIMARY_OUTLET} from './shared';
2828
export {UrlHandlingStrategy} from './url_handling_strategy';
2929
export {DefaultUrlSerializer, IsActiveMatchOptions, UrlSegment, UrlSegmentGroup, UrlSerializer, UrlTree} from './url_tree';
30+
export {mapToCanActivate, mapToCanActivateChild, mapToCanDeactivate, mapToCanMatch, mapToResolve} from './utils/functional_guards';
3031
export {VERSION} from './version';
3132

3233
export * from './private_export';
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {inject, Type} from '@angular/core';
10+
11+
import {CanActivateChildFn, CanActivateFn, CanDeactivateFn, CanMatchFn, ResolveFn} from '../models';
12+
13+
/**
14+
* Maps an array of injectable classes with canMatch functions to an array of equivalent
15+
* `CanMatchFn` for use in a `Route` definition.
16+
*
17+
* Usage {@example router/utils/functional_guards.ts region='CanActivate'}
18+
*
19+
* @publicApi
20+
* @see Route
21+
*/
22+
export function mapToCanMatch(providers: Array<Type<{canMatch: CanMatchFn}>>): CanMatchFn[] {
23+
return providers.map(provider => (...params) => inject(provider).canMatch(...params));
24+
}
25+
26+
/**
27+
* Maps an array of injectable classes with canActivate functions to an array of equivalent
28+
* `CanActivateFn` for use in a `Route` definition.
29+
*
30+
* Usage {@example router/utils/functional_guards.ts region='CanActivate'}
31+
*
32+
* @publicApi
33+
* @see Route
34+
*/
35+
export function mapToCanActivate(providers: Array<Type<{canActivate: CanActivateFn}>>):
36+
CanActivateFn[] {
37+
return providers.map(provider => (...params) => inject(provider).canActivate(...params));
38+
}
39+
/**
40+
* Maps an array of injectable classes with canActivateChild functions to an array of equivalent
41+
* `CanActivateChildFn` for use in a `Route` definition.
42+
*
43+
* Usage {@example router/utils/functional_guards.ts region='CanActivate'}
44+
*
45+
* @publicApi
46+
* @see Route
47+
*/
48+
export function mapToCanActivateChild(
49+
providers: Array<Type<{canActivateChild: CanActivateChildFn}>>): CanActivateChildFn[] {
50+
return providers.map(provider => (...params) => inject(provider).canActivateChild(...params));
51+
}
52+
/**
53+
* Maps an array of injectable classes with canDeactivate functions to an array of equivalent
54+
* `CanDeactivateFn` for use in a `Route` definition.
55+
*
56+
* Usage {@example router/utils/functional_guards.ts region='CanActivate'}
57+
*
58+
* @publicApi
59+
* @see Route
60+
*/
61+
export function mapToCanDeactivate<T = unknown>(
62+
providers: Array<Type<{canDeactivate: CanDeactivateFn<T>}>>): CanDeactivateFn<T>[] {
63+
return providers.map(provider => (...params) => inject(provider).canDeactivate(...params));
64+
}
65+
/**
66+
* Maps an injectable class with a resolve function to an equivalent `ResolveFn`
67+
* for use in a `Route` definition.
68+
*
69+
* Usage {@example router/utils/functional_guards.ts region='Resolve'}
70+
*
71+
* @publicApi
72+
* @see Route
73+
*/
74+
export function mapToResolve<T>(provider: Type<{resolve: ResolveFn<T>}>): ResolveFn<T> {
75+
return (...params) => inject(provider).resolve(...params);
76+
}

0 commit comments

Comments
 (0)