Revert "refactor(router): Simplify the prioritizeGuardValue logic" (#46759)

This reverts commit f32fface4763d789a8b7cc4f4489f98be4e1073a.

PR Close #46759
This commit is contained in:
Jessica Janiuk
2022-07-08 22:07:52 +00:00
parent 8124c78556
commit a003dd8dc2
@@ -7,43 +7,48 @@
*/
import {combineLatest, Observable, OperatorFunction} from 'rxjs';
import {filter, map, startWith, switchMap, take} from 'rxjs/operators';
import {filter, map, scan, startWith, switchMap, take} from 'rxjs/operators';
import {UrlTree} from '../url_tree';
import {isUrlTree} from '../utils/type_guards';
const INITIAL_VALUE = Symbol();
const INITIAL_VALUE = Symbol('INITIAL_VALUE');
declare type INTERIM_VALUES = typeof INITIAL_VALUE | boolean | UrlTree;
/**
* Takes an array of observables and returns the result of the first to emit something other than
* `true`.
*
* If all Observables emit `true`, then this operator emits true.
* Also note that only the first value of each observable is used.
*/
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))))
.pipe(
map((results: INTERIM_VALUES[]) => {
for (const result of results) {
if (result === true) {
// If result is true, check the next one
continue;
} else if (result === INITIAL_VALUE) {
// If guard has not finished, we need to stop processing.
return INITIAL_VALUE;
} else {
// Result finished and was not true. Return the result.
return result;
}
}
// Everything resolved to true. Return true.
return true;
}),
filter((item): item is boolean|UrlTree => item !== INITIAL_VALUE),
take(1),
);
.pipe(
scan(
(acc: INTERIM_VALUES, list: INTERIM_VALUES[]) => {
let isPending = false;
return list.reduce((innerAcc, val, i: number) => {
if (innerAcc !== INITIAL_VALUE) return innerAcc;
// Toggle pending flag if any values haven't been set yet
if (val === INITIAL_VALUE) isPending = true;
// Any other return values are only valid if we haven't yet hit a pending
// call. This guarantees that in the case of a guard at the bottom of the
// tree that returns a redirect, we will wait for the higher priority
// guard at the top to finish before performing the redirect.
if (!isPending) {
// Early return when we hit a `false` value as that should always
// cancel navigation
if (val === false) return val;
if (i === list.length - 1 || isUrlTree(val)) {
return val;
}
}
return innerAcc;
}, acc);
},
INITIAL_VALUE),
filter(item => item !== INITIAL_VALUE),
map(item => isUrlTree(item) ? item : item === true), //
take(1)) as Observable<boolean|UrlTree>;
});
}