Skip to content

Commit abe3759

Browse files
dimakubaAndrewKushnir
authored andcommitted
fix(router): allow to return UrlTree from CanMatchFn (#46455)
Currently it's not possible to return plain `UrlTree` from `CanMatchFn`, only wrapped `UrlTree` into Observable or Promise is allowed. These changes allow to return `UrlTree` from `CanMatchFn`. PR Close #46455
1 parent cb57cdb commit abe3759

3 files changed

Lines changed: 25 additions & 3 deletions

File tree

goldens/public-api/router/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ export interface CanMatch {
142142
}
143143

144144
// @public
145-
export type CanMatchFn = (route: Route, segments: UrlSegment[]) => Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean;
145+
export type CanMatchFn = (route: Route, segments: UrlSegment[]) => Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree;
146146

147147
// @public
148148
export class ChildActivationEnd {

packages/router/src/models.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,7 @@ export interface CanMatch {
915915
* @see `Route`
916916
*/
917917
export type CanMatchFn = (route: Route, segments: UrlSegment[]) =>
918-
Observable<boolean|UrlTree>|Promise<boolean|UrlTree>|boolean;
918+
Observable<boolean|UrlTree>|Promise<boolean|UrlTree>|boolean|UrlTree;
919919

920920
/**
921921
* @description

packages/router/test/integration.spec.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {ActivatedRoute, ActivatedRouteSnapshot, ActivationEnd, ActivationStart,
1616
import {EMPTY, Observable, Observer, of, Subscription} from 'rxjs';
1717
import {delay, filter, first, map, mapTo, tap} from 'rxjs/operators';
1818

19-
import {CanMatch} from '../src/models';
19+
import {CanMatch, CanMatchFn} from '../src/models';
2020
import {forEach} from '../src/utils/collection';
2121
import {getLoadedRoutes} from '../src/utils/config';
2222
import {RouterTestingModule} from '../testing';
@@ -4788,6 +4788,28 @@ describe('Integration', () => {
47884788
const fixture = createRoot(router, RootCmp);
47894789

47904790

4791+
router.navigateByUrl('/a');
4792+
advance(fixture);
4793+
expect(fixture.nativeElement.innerHTML).toContain('team');
4794+
}));
4795+
4796+
it('can return UrlTree from CanMatchFn guard', fakeAsync(() => {
4797+
const canMatchTeamSection = new InjectionToken('CanMatchTeamSection');
4798+
const canMatchFactory: (router: Router) => CanMatchFn = (router: Router) => () =>
4799+
router.createUrlTree(['/team/1']);
4800+
4801+
TestBed.overrideProvider(
4802+
canMatchTeamSection, {useFactory: canMatchFactory, deps: [Router]});
4803+
4804+
const router = TestBed.inject(Router);
4805+
4806+
router.resetConfig([
4807+
{path: 'a', canMatch: [canMatchTeamSection], component: SimpleCmp},
4808+
{path: 'team/:id', component: TeamCmp},
4809+
]);
4810+
const fixture = createRoot(router, RootCmp);
4811+
4812+
47914813
router.navigateByUrl('/a');
47924814
advance(fixture);
47934815
expect(fixture.nativeElement.innerHTML).toContain('team');

0 commit comments

Comments
 (0)