Skip to content

Commit 2a43bee

Browse files
atscottdylhunn
authored andcommitted
fix(router): Fix route recognition behavior with some versions of rxjs (#47098)
Some versions of rxjs cause the algorithm used in the Router to not recognize Route configs correctly. This commit updates the algorithm to be compatible in the same way as other code locations internally. Context: 1160b81 fixes #47089 Note: This does not have a test because I was unable to identify the version of rxjs that would cause a failure here. PR Close #47098
1 parent 91954cf commit 2a43bee

5 files changed

Lines changed: 20 additions & 8 deletions

File tree

packages/core/test/bundling/router/bundle.golden_symbols.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,6 +1436,9 @@
14361436
{
14371437
"name": "isDirectiveHost"
14381438
},
1439+
{
1440+
"name": "isEmptyError"
1441+
},
14391442
{
14401443
"name": "isFunction"
14411444
},

packages/router/src/apply_redirects.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import {EnvironmentInjector, ɵRuntimeError as RuntimeError} from '@angular/core';
10-
import {EmptyError, from, Observable, of, throwError} from 'rxjs';
10+
import {from, Observable, of, throwError} from 'rxjs';
1111
import {catchError, concatMap, first, last, map, mergeMap, scan, switchMap, tap} from 'rxjs/operators';
1212

1313
import {RuntimeErrorCode} from './errors';
@@ -21,6 +21,7 @@ import {createRoot, squashSegmentGroup, UrlSegment, UrlSegmentGroup, UrlSerializ
2121
import {forEach} from './utils/collection';
2222
import {getOrCreateRouteInjectorIfNeeded, getOutlet, sortByMatchingOutlets} from './utils/config';
2323
import {isImmediateMatch, match, matchWithChecks, noLeftoversInUrl, split} from './utils/config_matching';
24+
import {isEmptyError} from './utils/type_guards';
2425

2526
const NG_DEV_MODE = typeof ngDevMode === 'undefined' || ngDevMode;
2627

@@ -201,7 +202,7 @@ class ApplyRedirects {
201202
}));
202203
}),
203204
first((s): s is UrlSegmentGroup => !!s), catchError((e: any, _: any) => {
204-
if (e instanceof EmptyError || e.name === 'EmptyError') {
205+
if (isEmptyError(e)) {
205206
if (noLeftoversInUrl(segmentGroup, segments, outlet)) {
206207
return of(new UrlSegmentGroup([], {}));
207208
}

packages/router/src/operators/resolve_data.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import {EnvironmentInjector, ProviderToken} from '@angular/core';
10-
import {EMPTY, EmptyError, from, MonoTypeOperatorFunction, Observable, of, throwError} from 'rxjs';
10+
import {EMPTY, from, MonoTypeOperatorFunction, Observable, of, throwError} from 'rxjs';
1111
import {catchError, concatMap, first, map, mapTo, mergeMap, takeLast, tap} from 'rxjs/operators';
1212

1313
import {ResolveData, Route} from '../models';
@@ -17,6 +17,7 @@ import {RouteTitleKey} from '../shared';
1717
import {wrapIntoObservable} from '../utils/collection';
1818
import {getClosestRouteInjector} from '../utils/config';
1919
import {getTokenOrFunctionIdentity} from '../utils/preactivation';
20+
import {isEmptyError} from '../utils/type_guards';
2021

2122
export function resolveData(
2223
paramsInheritanceStrategy: 'emptyOnly'|'always',
@@ -74,7 +75,7 @@ function resolveNode(
7475
}))),
7576
takeLast(1),
7677
mapTo(data),
77-
catchError((e: unknown) => e instanceof EmptyError ? EMPTY : throwError(e)),
78+
catchError((e: unknown) => isEmptyError(e as Error) ? EMPTY : throwError(e)),
7879
);
7980
}
8081

packages/router/src/recognize.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,20 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {createEnvironmentInjector, EnvironmentInjector, Type, ɵRuntimeError as RuntimeError} from '@angular/core';
9+
import {EnvironmentInjector, Type, ɵRuntimeError as RuntimeError} from '@angular/core';
1010
import {EmptyError, from, Observable, Observer, of} from 'rxjs';
11-
import {catchError, concatMap, defaultIfEmpty, first, last as rxjsLast, map, scan, startWith, switchMap, takeLast, takeWhile} from 'rxjs/operators';
11+
import {catchError, concatMap, defaultIfEmpty, first, last as rxjsLast, map, scan, switchMap, takeWhile} from 'rxjs/operators';
1212

1313
import {RuntimeErrorCode} from './errors';
1414
import {Data, ResolveData, Route, Routes} from './models';
1515
import {ActivatedRouteSnapshot, inheritedParamsDataResolve, ParamsInheritanceStrategy, RouterStateSnapshot} from './router_state';
1616
import {PRIMARY_OUTLET} from './shared';
1717
import {UrlSegment, UrlSegmentGroup, UrlSerializer, UrlTree} from './url_tree';
1818
import {last} from './utils/collection';
19-
import {getOrCreateRouteInjectorIfNeeded, getOutlet, sortByMatchingOutlets} from './utils/config';
19+
import {getOutlet, sortByMatchingOutlets} from './utils/config';
2020
import {isImmediateMatch, matchWithChecks, noLeftoversInUrl, split} from './utils/config_matching';
2121
import {TreeNode} from './utils/tree';
22+
import {isEmptyError} from './utils/type_guards';
2223

2324
const NG_DEV_MODE = typeof ngDevMode === 'undefined' || !!ngDevMode;
2425

@@ -156,7 +157,7 @@ export class Recognizer {
156157
r._injector ?? injector, r, segmentGroup, segments, outlet);
157158
}),
158159
first((x): x is TreeNode<ActivatedRouteSnapshot>[] => !!x), catchError(e => {
159-
if (e instanceof EmptyError) {
160+
if (isEmptyError(e)) {
160161
if (noLeftoversInUrl(segmentGroup, segments, outlet)) {
161162
return of([]);
162163
}

packages/router/src/utils/type_guards.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9+
import {EmptyError} from 'rxjs';
10+
911
import {CanActivate, CanActivateChild, CanDeactivate, CanLoad, CanMatch} from '../models';
1012
import {NAVIGATION_CANCELING_ERROR, NavigationCancelingError, RedirectingNavigationCancelingError} from '../navigation_canceling_error';
1113
import {isUrlTree} from '../url_tree';
@@ -59,3 +61,7 @@ export function isRedirectingNavigationCancelingError(
5961
export function isNavigationCancelingError(error: unknown): error is NavigationCancelingError {
6062
return error && (error as any)[NAVIGATION_CANCELING_ERROR];
6163
}
64+
65+
export function isEmptyError(e: Error): e is EmptyError {
66+
return e instanceof EmptyError || e?.name === 'EmptyError';
67+
}

0 commit comments

Comments
 (0)