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
This commit is contained in:
Dmitrij Kuba
2022-06-22 18:52:57 +03:00
committed by Andrew Kushnir
parent cb57cdbbd4
commit abe3759e24
3 changed files with 25 additions and 3 deletions
+1 -1
View File
@@ -142,7 +142,7 @@ export interface CanMatch {
}
// @public
export type CanMatchFn = (route: Route, segments: UrlSegment[]) => Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean;
export type CanMatchFn = (route: Route, segments: UrlSegment[]) => Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree;
// @public
export class ChildActivationEnd {
+1 -1
View File
@@ -915,7 +915,7 @@ export interface CanMatch {
* @see `Route`
*/
export type CanMatchFn = (route: Route, segments: UrlSegment[]) =>
Observable<boolean|UrlTree>|Promise<boolean|UrlTree>|boolean;
Observable<boolean|UrlTree>|Promise<boolean|UrlTree>|boolean|UrlTree;
/**
* @description
+23 -1
View File
@@ -16,7 +16,7 @@ import {ActivatedRoute, ActivatedRouteSnapshot, ActivationEnd, ActivationStart,
import {EMPTY, Observable, Observer, of, Subscription} from 'rxjs';
import {delay, filter, first, map, mapTo, tap} from 'rxjs/operators';
import {CanMatch} from '../src/models';
import {CanMatch, CanMatchFn} from '../src/models';
import {forEach} from '../src/utils/collection';
import {getLoadedRoutes} from '../src/utils/config';
import {RouterTestingModule} from '../testing';
@@ -4788,6 +4788,28 @@ describe('Integration', () => {
const fixture = createRoot(router, RootCmp);
router.navigateByUrl('/a');
advance(fixture);
expect(fixture.nativeElement.innerHTML).toContain('team');
}));
it('can return UrlTree from CanMatchFn guard', fakeAsync(() => {
const canMatchTeamSection = new InjectionToken('CanMatchTeamSection');
const canMatchFactory: (router: Router) => CanMatchFn = (router: Router) => () =>
router.createUrlTree(['/team/1']);
TestBed.overrideProvider(
canMatchTeamSection, {useFactory: canMatchFactory, deps: [Router]});
const router = TestBed.inject(Router);
router.resetConfig([
{path: 'a', canMatch: [canMatchTeamSection], component: SimpleCmp},
{path: 'team/:id', component: TeamCmp},
]);
const fixture = createRoot(router, RootCmp);
router.navigateByUrl('/a');
advance(fixture);
expect(fixture.nativeElement.innerHTML).toContain('team');