Skip to content

Commit

Permalink
refactor(router): Move runCanLoadGuards to same location as similar f…
Browse files Browse the repository at this point in the history
…unctions (#46021)

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

PR Close #46021
  • Loading branch information
atscott authored and jessicajaniuk committed Jun 13, 2022
1 parent 9ab3261 commit 96f5c97
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 40 deletions.
36 changes: 2 additions & 34 deletions packages/router/src/apply_redirects.ts
Expand Up @@ -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';
Expand Down Expand Up @@ -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)
Expand All @@ -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;
Expand Down
57 changes: 51 additions & 6 deletions packages/router/src/operators/check_guards.ts
Expand Up @@ -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';

Expand Down Expand Up @@ -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),
);
}

0 comments on commit 96f5c97

Please sign in to comment.