Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion goldens/size-tracking/integration-payloads.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,4 @@
}
}
}
}
}
12 changes: 0 additions & 12 deletions packages/core/test/bundling/router/bundle.golden_symbols.json
Original file line number Diff line number Diff line change
Expand Up @@ -1238,12 +1238,6 @@
{
"name": "findPath"
},
{
"name": "fireActivationStart"
},
{
"name": "fireChildActivationStart"
},
{
"name": "first"
},
Expand Down Expand Up @@ -1832,12 +1826,6 @@
{
"name": "routerNgProbeToken"
},
{
"name": "runCanActivate"
},
{
"name": "runCanActivateChild"
},
{
"name": "rxSubscriber"
},
Expand Down
10 changes: 4 additions & 6 deletions packages/router/src/directives/router_link_active.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,10 @@ export class RouterLinkActive implements OnChanges, OnDestroy, AfterContentInit
/** @nodoc */
ngAfterContentInit(): void {
// `of(null)` is used to force subscribe body to execute once immediately (like `startWith`).
from([this.links.changes, this.linksWithHrefs.changes, of(null)])
.pipe(mergeAll())
.subscribe(_ => {
this.update();
this.subscribeToEachLinkOnChanges();
});
of(this.links.changes, this.linksWithHrefs.changes, of(null)).pipe(mergeAll()).subscribe(_ => {
this.update();
this.subscribeToEachLinkOnChanges();
});
}

private subscribeToEachLinkOnChanges() {
Expand Down
10 changes: 4 additions & 6 deletions packages/router/src/operators/apply_redirects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

import {Injector} from '@angular/core';
import {MonoTypeOperatorFunction, Observable} from 'rxjs';
import {MonoTypeOperatorFunction} from 'rxjs';
import {map, switchMap} from 'rxjs/operators';

import {applyRedirects as applyRedirectsFn} from '../apply_redirects';
Expand All @@ -19,9 +19,7 @@ import {UrlSerializer} from '../url_tree';
export function applyRedirects(
moduleInjector: Injector, configLoader: RouterConfigLoader, urlSerializer: UrlSerializer,
config: Routes): MonoTypeOperatorFunction<NavigationTransition> {
return function(source: Observable<NavigationTransition>) {
return source.pipe(switchMap(
t => applyRedirectsFn(moduleInjector, configLoader, urlSerializer, t.extractedUrl, config)
.pipe(map(urlAfterRedirects => ({...t, urlAfterRedirects})))));
};
return switchMap(
t => applyRedirectsFn(moduleInjector, configLoader, urlSerializer, t.extractedUrl, config)
.pipe(map(urlAfterRedirects => ({...t, urlAfterRedirects}))));
}
52 changes: 23 additions & 29 deletions packages/router/src/operators/check_guards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
*/

import {Injector} from '@angular/core';
import {defer, from, MonoTypeOperatorFunction, Observable, of} from 'rxjs';
import {concatAll, concatMap, first, map, mergeMap} from 'rxjs/operators';
import {concat, defer, from, MonoTypeOperatorFunction, Observable, of} from 'rxjs';
import {concatMap, first, map, mergeMap} from 'rxjs/operators';

import {ActivationStart, ChildActivationStart, Event} from '../events';
import {CanActivateChildFn, CanActivateFn, CanDeactivateFn} from '../interfaces';
Expand All @@ -23,25 +23,23 @@ import {prioritizedGuardValue} from './prioritized_guard_value';

export function checkGuards(moduleInjector: Injector, forwardEvent?: (evt: Event) => void):
MonoTypeOperatorFunction<NavigationTransition> {
return function(source: Observable<NavigationTransition>) {
return source.pipe(mergeMap(t => {
const {targetSnapshot, currentSnapshot, guards: {canActivateChecks, canDeactivateChecks}} = t;
if (canDeactivateChecks.length === 0 && canActivateChecks.length === 0) {
return of({...t, guardsResult: true});
}
return mergeMap(t => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing these wrapper functions was a great change. Thanks!

const {targetSnapshot, currentSnapshot, guards: {canActivateChecks, canDeactivateChecks}} = t;
if (canDeactivateChecks.length === 0 && canActivateChecks.length === 0) {
return of({...t, guardsResult: true});
}

return runCanDeactivateChecks(
canDeactivateChecks, targetSnapshot!, currentSnapshot, moduleInjector)
.pipe(
mergeMap(canDeactivate => {
return canDeactivate && isBoolean(canDeactivate) ?
runCanActivateChecks(
targetSnapshot!, canActivateChecks, moduleInjector, forwardEvent) :
of(canDeactivate);
}),
map(guardsResult => ({...t, guardsResult})));
}));
};
return runCanDeactivateChecks(
canDeactivateChecks, targetSnapshot!, currentSnapshot, moduleInjector)
.pipe(
mergeMap(canDeactivate => {
return canDeactivate && isBoolean(canDeactivate) ?
runCanActivateChecks(
targetSnapshot!, canActivateChecks, moduleInjector, forwardEvent) :
of(canDeactivate);
}),
map(guardsResult => ({...t, guardsResult})));
});
}

function runCanDeactivateChecks(
Expand All @@ -61,15 +59,11 @@ function runCanActivateChecks(
forwardEvent?: (evt: Event) => void) {
return from(checks).pipe(
concatMap((check: CanActivate) => {
return from([
fireChildActivationStart(check.route.parent, forwardEvent),
fireActivationStart(check.route, forwardEvent),
runCanActivateChild(futureSnapshot, check.path, moduleInjector),
runCanActivate(futureSnapshot, check.route, moduleInjector)
])
.pipe(concatAll(), first(result => {
return result !== true;
}, true as boolean | UrlTree));
return concat(
fireChildActivationStart(check.route.parent, forwardEvent),
fireActivationStart(check.route, forwardEvent),
runCanActivateChild(futureSnapshot, check.path, moduleInjector),
runCanActivate(futureSnapshot, check.route, moduleInjector));
}),
first(result => {
return result !== true;
Expand Down
3 changes: 1 addition & 2 deletions packages/router/src/operators/prioritized_guard_value.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ declare type INTERIM_VALUES = typeof INITIAL_VALUE | boolean | UrlTree;
export function prioritizedGuardValue():
OperatorFunction<Observable<boolean|UrlTree>[], boolean|UrlTree> {
return switchMap(obs => {
return combineLatest(
...obs.map(o => o.pipe(take(1), startWith(INITIAL_VALUE as INTERIM_VALUES))))
return combineLatest(obs.map(o => o.pipe(take(1), startWith(INITIAL_VALUE as INTERIM_VALUES))))
.pipe(
scan(
(acc: INTERIM_VALUES, list: INTERIM_VALUES[]) => {
Expand Down
14 changes: 6 additions & 8 deletions packages/router/src/operators/recognize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

import {Type} from '@angular/core';
import {MonoTypeOperatorFunction, Observable} from 'rxjs';
import {MonoTypeOperatorFunction} from 'rxjs';
import {map, mergeMap} from 'rxjs/operators';

import {Route} from '../config';
Expand All @@ -19,11 +19,9 @@ export function recognize(
rootComponentType: Type<any>|null, config: Route[], serializer: (url: UrlTree) => string,
paramsInheritanceStrategy: 'emptyOnly'|'always',
relativeLinkResolution: 'legacy'|'corrected'): MonoTypeOperatorFunction<NavigationTransition> {
return function(source: Observable<NavigationTransition>) {
return source.pipe(mergeMap(
t => recognizeFn(
rootComponentType, config, t.urlAfterRedirects, serializer(t.urlAfterRedirects),
paramsInheritanceStrategy, relativeLinkResolution)
.pipe(map(targetSnapshot => ({...t, targetSnapshot})))));
};
return mergeMap(
t => recognizeFn(
rootComponentType, config, t.urlAfterRedirects, serializer(t.urlAfterRedirects),
paramsInheritanceStrategy, relativeLinkResolution)
.pipe(map(targetSnapshot => ({...t, targetSnapshot}))));
}
34 changes: 16 additions & 18 deletions packages/router/src/operators/resolve_data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,23 @@ import {getToken} from '../utils/preactivation';
export function resolveData(
paramsInheritanceStrategy: 'emptyOnly'|'always',
moduleInjector: Injector): MonoTypeOperatorFunction<NavigationTransition> {
return function(source: Observable<NavigationTransition>) {
return source.pipe(mergeMap(t => {
const {targetSnapshot, guards: {canActivateChecks}} = t;
return mergeMap(t => {
const {targetSnapshot, guards: {canActivateChecks}} = t;

if (!canActivateChecks.length) {
return of(t);
}
let canActivateChecksResolved = 0;
return from(canActivateChecks)
.pipe(
concatMap(
check => runResolve(
check.route, targetSnapshot!, paramsInheritanceStrategy, moduleInjector)),
tap(() => canActivateChecksResolved++),
takeLast(1),
mergeMap(_ => canActivateChecksResolved === canActivateChecks.length ? of(t) : EMPTY),
);
}));
};
if (!canActivateChecks.length) {
return of(t);
}
let canActivateChecksResolved = 0;
return from(canActivateChecks)
.pipe(
concatMap(
check => runResolve(
check.route, targetSnapshot!, paramsInheritanceStrategy, moduleInjector)),
tap(() => canActivateChecksResolved++),
takeLast(1),
mergeMap(_ => canActivateChecksResolved === canActivateChecks.length ? of(t) : EMPTY),
);
});
}

function runResolve(
Expand Down
18 changes: 8 additions & 10 deletions packages/router/src/operators/switch_tap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/

import {from, MonoTypeOperatorFunction, ObservableInput} from 'rxjs';
import {from, MonoTypeOperatorFunction, ObservableInput, of} from 'rxjs';
import {map, switchMap} from 'rxjs/operators';

/**
Expand All @@ -17,13 +17,11 @@ import {map, switchMap} from 'rxjs/operators';
*/
export function switchTap<T>(next: (x: T) => void|ObservableInput<any>):
MonoTypeOperatorFunction<T> {
return function(source) {
return source.pipe(switchMap(v => {
const nextResult = next(v);
if (nextResult) {
return from(nextResult).pipe(map(() => v));
}
return from([v]);
}));
};
return switchMap(v => {
const nextResult = next(v);
if (nextResult) {
return from(nextResult).pipe(map(() => v));
}
return of(v);
});
}
17 changes: 6 additions & 11 deletions packages/router/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -573,12 +573,11 @@ export class Router {
if (transition !== this.transitions.getValue()) {
return EMPTY;
}
return [t];
}),

// This delay is required to match old behavior that forced navigation
// to always be async
switchMap(t => Promise.resolve(t)),
// This delay is required to match old behavior that forced
// navigation to always be async
return Promise.resolve(t);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like the removal of the taps. The Router rxjs chain is hard enough to follow without extra operators thrown in there.

}),

// ApplyRedirects
applyRedirects(
Expand Down Expand Up @@ -609,10 +608,8 @@ export class Router {
}
this.browserUrlTree = t.urlAfterRedirects;
}
}),

// Fire RoutesRecognized
tap(t => {
// Fire RoutesRecognized
const routesRecognized = new RoutesRecognized(
t.id, this.serializeUrl(t.extractedUrl),
this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot!);
Expand Down Expand Up @@ -692,9 +689,7 @@ export class Router {
error.url = t.guardsResult;
throw error;
}
}),

tap(t => {
const guardsEnd = new GuardsCheckEnd(
t.id, this.serializeUrl(t.extractedUrl),
this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot!,
Expand Down Expand Up @@ -875,7 +870,7 @@ export class Router {
replaceUrl: this.urlUpdateStrategy === 'eager'
};

return this.scheduleNavigation(
this.scheduleNavigation(
mergedTree, 'imperative', null, extras,
{resolve: t.resolve, reject: t.reject, promise: t.promise});
}, 0);
Expand Down
3 changes: 1 addition & 2 deletions packages/router/src/utils/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@

import {ɵisObservable as isObservable, ɵisPromise as isPromise} from '@angular/core';
import {from, Observable, of} from 'rxjs';
import {concatAll, last as lastValue, map} from 'rxjs/operators';

import {Params, PRIMARY_OUTLET} from '../shared';
import {Params} from '../shared';

export function shallowEqualArrays(a: any[], b: any[]): boolean {
if (a.length !== b.length) return false;
Expand Down