refactor(router): Move runCanLoadGuards to same location as similar functions (#46021)

This commit moves the runCanLoadGuards to the same location as other guard execution functions

PR Close #46021
This commit is contained in:
Andrew Scott
2022-02-04 10:51:45 -08:00
committed by Jessica Janiuk
parent 9ab32616aa
commit 96f5c971ba
2 changed files with 53 additions and 40 deletions
+2 -34
View File
@@ -11,6 +11,7 @@ import {EmptyError, from, Observable, of, throwError} from 'rxjs';
import {catchError, concatMap, first, last, map, mergeMap, scan, tap} from 'rxjs/operators';
import {CanLoadFn, LoadedRouterConfig, Route, Routes} from './models';
import {runCanLoadGuards} from './operators/check_guards';
import {prioritizedGuardValue} from './operators/prioritized_guard_value';
import {RouterConfigLoader} from './router_config_loader';
import {navigationCancelingError, Params, PRIMARY_OUTLET} from './shared';
@@ -335,7 +336,7 @@ class ApplyRedirects {
return of({routes: route._loadedRoutes, injector: route._loadedInjector});
}
return this.runCanLoadGuards(injector, route, segments)
return runCanLoadGuards(injector, route, segments, this.urlSerializer)
.pipe(mergeMap((shouldLoadResult: boolean) => {
if (shouldLoadResult) {
return this.configLoader.loadChildren(injector, route)
@@ -351,39 +352,6 @@ class ApplyRedirects {
return of({routes: [], injector});
}
private runCanLoadGuards(injector: EnvironmentInjector, route: Route, segments: UrlSegment[]):
Observable<boolean> {
const canLoad = route.canLoad;
if (!canLoad || canLoad.length === 0) return of(true);
const canLoadObservables = canLoad.map((injectionToken: any) => {
const guard = injector.get(injectionToken);
let guardVal;
if (isCanLoad(guard)) {
guardVal = guard.canLoad(route, segments);
} else if (isFunction<CanLoadFn>(guard)) {
guardVal = guard(route, segments);
} else {
throw new Error('Invalid CanLoad guard');
}
return wrapIntoObservable(guardVal);
});
return of(canLoadObservables)
.pipe(
prioritizedGuardValue(),
tap((result: UrlTree|boolean) => {
if (!isUrlTree(result)) return;
const error: Error&{url?: UrlTree} = navigationCancelingError(
`Redirecting to "${this.urlSerializer.serialize(result)}"`);
error.url = result;
throw error;
}),
map(result => result === true),
);
}
private lineralizeSegments(route: Route, urlTree: UrlTree): Observable<UrlSegment[]> {
let res: UrlSegment[] = [];
let c = urlTree.root;
+51 -6
View File
@@ -6,18 +6,19 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Injector} from '@angular/core';
import {concat, defer, from, MonoTypeOperatorFunction, Observable, of} from 'rxjs';
import {concatMap, first, map, mergeMap} from 'rxjs/operators';
import {EnvironmentInjector, Injector} from '@angular/core';
import {concat, defer, from, MonoTypeOperatorFunction, Observable, of, OperatorFunction, pipe} from 'rxjs';
import {concatMap, first, map, mergeMap, tap} from 'rxjs/operators';
import {ActivationStart, ChildActivationStart, Event} from '../events';
import {CanActivateChildFn, CanActivateFn, CanDeactivateFn} from '../models';
import {CanActivateChildFn, CanActivateFn, CanDeactivateFn, CanLoadFn, Route} from '../models';
import {NavigationTransition} from '../router';
import {ActivatedRouteSnapshot, RouterStateSnapshot} from '../router_state';
import {UrlTree} from '../url_tree';
import {navigationCancelingError} from '../shared';
import {UrlSegment, UrlSerializer, UrlTree} from '../url_tree';
import {wrapIntoObservable} from '../utils/collection';
import {CanActivate, CanDeactivate, getCanActivateChild, getToken} from '../utils/preactivation';
import {isBoolean, isCanActivate, isCanActivateChild, isCanDeactivate, isFunction} from '../utils/type_guards';
import {isBoolean, isCanActivate, isCanActivateChild, isCanDeactivate, isCanLoad, isFunction, isUrlTree} from '../utils/type_guards';
import {prioritizedGuardValue} from './prioritized_guard_value';
@@ -176,3 +177,47 @@ function runCanDeactivate(
});
return of(canDeactivateObservables).pipe(prioritizedGuardValue());
}
export function runCanLoadGuards(
injector: EnvironmentInjector, route: Route, segments: UrlSegment[],
urlSerializer: UrlSerializer): Observable<boolean> {
const canLoad = route.canLoad;
if (canLoad === undefined || canLoad.length === 0) {
return of(true);
}
const canLoadObservables = canLoad.map((injectionToken: any) => {
const guard = injector.get(injectionToken);
let guardVal;
if (isCanLoad(guard)) {
guardVal = guard.canLoad(route, segments);
} else if (isFunction<CanLoadFn>(guard)) {
guardVal = guard(route, segments);
} else {
throw new Error('Invalid CanLoad guard');
}
return wrapIntoObservable(guardVal);
});
return of(canLoadObservables)
.pipe(
prioritizedGuardValue(),
redirectIfUrlTree(urlSerializer),
);
}
function redirectIfUrlTree(urlSerializer: UrlSerializer):
OperatorFunction<UrlTree|boolean, boolean> {
return pipe(
tap((result: UrlTree|boolean) => {
if (!isUrlTree(result)) return;
const error: Error&{url?: UrlTree} =
navigationCancelingError(`Redirecting to "${urlSerializer.serialize(result)}"`);
error.url = result;
throw error;
}),
map(result => result === true),
);
}