Skip to content

Commit b9e32c8

Browse files
Dzmitry Shylovichmhevery
authored andcommitted
fix(router): child CanActivate guard should wait for parent to complete (#18110)
Closes #15670 PR Close #18110
1 parent be49e0e commit b9e32c8

2 files changed

Lines changed: 54 additions & 1 deletion

File tree

‎packages/router/src/router.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -930,7 +930,7 @@ export class PreActivation {
930930

931931
private runCanActivateChecks(): Observable<boolean> {
932932
const checks$ = from(this.canActivateChecks);
933-
const runningChecks$ = mergeMap.call(
933+
const runningChecks$ = concatMap.call(
934934
checks$, (check: CanActivate) => andObservables(from(
935935
[this.runCanActivateChild(check.path), this.runCanActivate(check.route)])));
936936
return every.call(runningChecks$, (result: boolean) => result === true);

‎packages/router/test/integration.spec.ts‎

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1789,6 +1789,59 @@ describe('Integration', () => {
17891789
})));
17901790
});
17911791

1792+
describe('should wait for parent to complete', () => {
1793+
let log: string[];
1794+
1795+
beforeEach(() => {
1796+
log = [];
1797+
TestBed.configureTestingModule({
1798+
providers: [
1799+
{
1800+
provide: 'parentGuard',
1801+
useValue: () => {
1802+
return delayPromise(10).then(() => {
1803+
log.push('parent');
1804+
return true;
1805+
});
1806+
}
1807+
},
1808+
{
1809+
provide: 'childGuard',
1810+
useValue: () => {
1811+
return delayPromise(5).then(() => {
1812+
log.push('child');
1813+
return true;
1814+
});
1815+
}
1816+
}
1817+
]
1818+
});
1819+
});
1820+
1821+
function delayPromise(delay: number): Promise<boolean> {
1822+
let resolve: (val: boolean) => void;
1823+
const promise = new Promise(res => resolve = res);
1824+
setTimeout(() => resolve(true), delay);
1825+
return promise;
1826+
}
1827+
1828+
it('works', fakeAsync(inject([Router], (router: Router) => {
1829+
const fixture = createRoot(router, RootCmp);
1830+
1831+
router.resetConfig([{
1832+
path: 'parent',
1833+
canActivate: ['parentGuard'],
1834+
children: [
1835+
{path: 'child', component: SimpleCmp, canActivate: ['childGuard']},
1836+
]
1837+
}]);
1838+
1839+
router.navigateByUrl('/parent/child');
1840+
advance(fixture);
1841+
tick(15);
1842+
expect(log).toEqual(['parent', 'child']);
1843+
})));
1844+
});
17921845
});
17931846

17941847
describe('CanDeactivate', () => {

0 commit comments

Comments
 (0)