Created
December 4, 2018 08:18
-
-
Save nathan-lapinski/165756938ada5a0574a8c032735ce8a7 to your computer and use it in GitHub Desktop.
excerpt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const INITIAL_VALUE = Symbol('INITIAL_VALUE'); | |
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)))) | |
.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), // why is INITIAL_VALUE here if it's just filtered? Just to make sure this works with 0 guards? | |
map(item => isUrlTree(item) ? item : item === true), // why item === true? The return type is just UrlTree or boolean, yea? | |
take(1)) as Observable<boolean|UrlTree>; // only one guard's UrlTree should win. Is that what this is doing? How are boolean vals handled? | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment