fix(router): child CanActivate guard should wait for parent to complete (#18110)
Closes #15670 PR Close #18110
This commit is contained in:
parent
be49e0ee93
commit
b9e32c833a
@ -930,7 +930,7 @@ export class PreActivation {
|
|||||||
|
|
||||||
private runCanActivateChecks(): Observable<boolean> {
|
private runCanActivateChecks(): Observable<boolean> {
|
||||||
const checks$ = from(this.canActivateChecks);
|
const checks$ = from(this.canActivateChecks);
|
||||||
const runningChecks$ = mergeMap.call(
|
const runningChecks$ = concatMap.call(
|
||||||
checks$, (check: CanActivate) => andObservables(from(
|
checks$, (check: CanActivate) => andObservables(from(
|
||||||
[this.runCanActivateChild(check.path), this.runCanActivate(check.route)])));
|
[this.runCanActivateChild(check.path), this.runCanActivate(check.route)])));
|
||||||
return every.call(runningChecks$, (result: boolean) => result === true);
|
return every.call(runningChecks$, (result: boolean) => result === true);
|
||||||
|
@ -1789,6 +1789,59 @@ describe('Integration', () => {
|
|||||||
})));
|
})));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('should wait for parent to complete', () => {
|
||||||
|
let log: string[];
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
log = [];
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: 'parentGuard',
|
||||||
|
useValue: () => {
|
||||||
|
return delayPromise(10).then(() => {
|
||||||
|
log.push('parent');
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: 'childGuard',
|
||||||
|
useValue: () => {
|
||||||
|
return delayPromise(5).then(() => {
|
||||||
|
log.push('child');
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function delayPromise(delay: number): Promise<boolean> {
|
||||||
|
let resolve: (val: boolean) => void;
|
||||||
|
const promise = new Promise(res => resolve = res);
|
||||||
|
setTimeout(() => resolve(true), delay);
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
it('works', fakeAsync(inject([Router], (router: Router) => {
|
||||||
|
const fixture = createRoot(router, RootCmp);
|
||||||
|
|
||||||
|
router.resetConfig([{
|
||||||
|
path: 'parent',
|
||||||
|
canActivate: ['parentGuard'],
|
||||||
|
children: [
|
||||||
|
{path: 'child', component: SimpleCmp, canActivate: ['childGuard']},
|
||||||
|
]
|
||||||
|
}]);
|
||||||
|
|
||||||
|
router.navigateByUrl('/parent/child');
|
||||||
|
advance(fixture);
|
||||||
|
tick(15);
|
||||||
|
expect(log).toEqual(['parent', 'child']);
|
||||||
|
})));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('CanDeactivate', () => {
|
describe('CanDeactivate', () => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user