77 */
88
99import { Injector , runInInjectionContext , ɵRuntimeError as RuntimeError } from '@angular/core' ;
10- import { Observable , of , throwError } from 'rxjs' ;
11- import { map } from 'rxjs/operators' ;
1210
1311import { RuntimeErrorCode } from './errors' ;
1412import { NavigationCancellationCode } from './events' ;
15- import { LoadedRouterConfig , RedirectFunction , Route } from './models' ;
13+ import { RedirectFunction , Route } from './models' ;
1614import { navigationCancelingError } from './navigation_canceling_error' ;
1715import { ActivatedRouteSnapshot } from './router_state' ;
1816import { Params , PRIMARY_OUTLET } from './shared' ;
1917import { UrlSegment , UrlSegmentGroup , UrlSerializer , UrlTree } from './url_tree' ;
2018import { wrapIntoObservable } from './utils/collection' ;
2119
22- export class NoMatch {
20+ export const NO_MATCH_ERROR_NAME = 'ɵNoMatch' ;
21+ export class NoMatch extends Error {
22+ override readonly name : string = NO_MATCH_ERROR_NAME ;
2323 public segmentGroup : UrlSegmentGroup | null ;
2424
2525 constructor ( segmentGroup ?: UrlSegmentGroup ) {
26+ super ( ) ;
2627 this . segmentGroup = segmentGroup || null ;
2728 }
2829}
2930
31+ export const ABSOLUTE_REDIRECT_ERROR_NAME = 'ɵAbsoluteRedirect' ;
3032export class AbsoluteRedirect extends Error {
33+ override readonly name : string = ABSOLUTE_REDIRECT_ERROR_NAME ;
3134 constructor ( public urlTree : UrlTree ) {
3235 super ( ) ;
3336 }
3437}
3538
36- export function noMatch ( segmentGroup : UrlSegmentGroup ) : Observable < any > {
37- return throwError ( new NoMatch ( segmentGroup ) ) ;
38- }
39-
40- export function absoluteRedirect ( newTree : UrlTree ) : Observable < any > {
41- return throwError ( new AbsoluteRedirect ( newTree ) ) ;
42- }
43-
44- export function namedOutletsRedirect ( redirectTo : string ) : Observable < any > {
45- return throwError (
46- new RuntimeError (
47- RuntimeErrorCode . NAMED_OUTLET_REDIRECT ,
48- ( typeof ngDevMode === 'undefined' || ngDevMode ) &&
49- `Only absolute redirects can have named outlets. redirectTo: '${ redirectTo } '` ,
50- ) ,
39+ export function namedOutletsRedirect ( redirectTo : string ) : never {
40+ throw new RuntimeError (
41+ RuntimeErrorCode . NAMED_OUTLET_REDIRECT ,
42+ ( typeof ngDevMode === 'undefined' || ngDevMode ) &&
43+ `Only absolute redirects can have named outlets. redirectTo: '${ redirectTo } '` ,
5144 ) ;
5245}
5346
54- export function canLoadFails ( route : Route ) : Observable < LoadedRouterConfig > {
55- return throwError (
56- navigationCancelingError (
57- ( typeof ngDevMode === 'undefined' || ngDevMode ) &&
58- `Cannot load children because the guard of the route "path: '${ route . path } '" returned false` ,
59- NavigationCancellationCode . GuardRejected ,
60- ) ,
47+ export function canLoadFails ( route : Route ) : never {
48+ throw navigationCancelingError (
49+ ( typeof ngDevMode === 'undefined' || ngDevMode ) &&
50+ `Cannot load children because the guard of the route "path: '${ route . path } '" returned false` ,
51+ NavigationCancellationCode . GuardRejected ,
6152 ) ;
6253}
6354
@@ -67,49 +58,46 @@ export class ApplyRedirects {
6758 private urlTree : UrlTree ,
6859 ) { }
6960
70- lineralizeSegments ( route : Route , urlTree : UrlTree ) : Observable < UrlSegment [ ] > {
61+ async lineralizeSegments ( route : Route , urlTree : UrlTree ) : Promise < UrlSegment [ ] > {
7162 let res : UrlSegment [ ] = [ ] ;
7263 let c = urlTree . root ;
7364 while ( true ) {
7465 res = res . concat ( c . segments ) ;
7566 if ( c . numberOfChildren === 0 ) {
76- return of ( res ) ;
67+ return res ;
7768 }
7869
7970 if ( c . numberOfChildren > 1 || ! c . children [ PRIMARY_OUTLET ] ) {
80- return namedOutletsRedirect ( `${ route . redirectTo ! } ` ) ;
71+ throw namedOutletsRedirect ( `${ route . redirectTo ! } ` ) ;
8172 }
8273
8374 c = c . children [ PRIMARY_OUTLET ] ;
8475 }
8576 }
8677
87- applyRedirectCommands (
78+ async applyRedirectCommands (
8879 segments : UrlSegment [ ] ,
8980 redirectTo : string | RedirectFunction ,
9081 posParams : { [ k : string ] : UrlSegment } ,
9182 currentSnapshot : ActivatedRouteSnapshot ,
9283 injector : Injector ,
93- ) : Observable < UrlTree > {
94- return getRedirectResult ( redirectTo , currentSnapshot , injector ) . pipe (
95- map ( ( redirect ) => {
96- if ( redirect instanceof UrlTree ) {
97- throw new AbsoluteRedirect ( redirect ) ;
98- }
99-
100- const newTree = this . applyRedirectCreateUrlTree (
101- redirect ,
102- this . urlSerializer . parse ( redirect ) ,
103- segments ,
104- posParams ,
105- ) ;
106-
107- if ( redirect [ 0 ] === '/' ) {
108- throw new AbsoluteRedirect ( newTree ) ;
109- }
110- return newTree ;
111- } ) ,
84+ ) : Promise < UrlTree > {
85+ const redirect = await getRedirectResult ( redirectTo , currentSnapshot , injector ) ;
86+ if ( redirect instanceof UrlTree ) {
87+ throw new AbsoluteRedirect ( redirect ) ;
88+ }
89+
90+ const newTree = this . applyRedirectCreateUrlTree (
91+ redirect ,
92+ this . urlSerializer . parse ( redirect ) ,
93+ segments ,
94+ posParams ,
11295 ) ;
96+
97+ if ( redirect [ 0 ] === '/' ) {
98+ throw new AbsoluteRedirect ( newTree ) ;
99+ }
100+ return newTree ;
113101 }
114102
115103 applyRedirectCreateUrlTree (
@@ -201,15 +189,15 @@ function getRedirectResult(
201189 redirectTo : string | RedirectFunction ,
202190 currentSnapshot : ActivatedRouteSnapshot ,
203191 injector : Injector ,
204- ) : Observable < string | UrlTree > {
192+ ) : Promise < string | UrlTree > {
205193 if ( typeof redirectTo === 'string' ) {
206- return of ( redirectTo ) ;
194+ return Promise . resolve ( redirectTo ) ;
207195 }
208196 const redirectToFn = redirectTo ;
209197 const { queryParams, fragment, routeConfig, url, outlet, params, data, title} = currentSnapshot ;
210198 return wrapIntoObservable (
211199 runInInjectionContext ( injector , ( ) =>
212200 redirectToFn ( { params, data, queryParams, fragment, routeConfig, url, outlet, title} ) ,
213201 ) ,
214- ) ;
202+ ) . toPromise ( ) as Promise < string | UrlTree > ;
215203}
0 commit comments