diff --git a/packages/router/src/router.ts b/packages/router/src/router.ts index 4c61c68fc7..a5970a15a6 100644 --- a/packages/router/src/router.ts +++ b/packages/router/src/router.ts @@ -930,7 +930,7 @@ export class PreActivation { private runCanActivateChecks(): Observable { const checks$ = from(this.canActivateChecks); - const runningChecks$ = mergeMap.call( + const runningChecks$ = concatMap.call( checks$, (check: CanActivate) => andObservables(from( [this.runCanActivateChild(check.path), this.runCanActivate(check.route)]))); return every.call(runningChecks$, (result: boolean) => result === true); diff --git a/packages/router/test/integration.spec.ts b/packages/router/test/integration.spec.ts index 571406626f..89c5443ae4 100644 --- a/packages/router/test/integration.spec.ts +++ b/packages/router/test/integration.spec.ts @@ -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 { + 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', () => {