Skip to content

Commit ea19683

Browse files
zbirkenbueljosephperrott
authored andcommitted
fix(router): update getRouteGuards to check if the context outlet is activated (angular#39049)
In certain circumstances (errors during component constructor) the router outlet may not be activated before redirecting to a new route. If the new route requires running guards and resolvers the current logic will throw when accessing outlet.component due to an isActivated check within the property getter. This update brings the logic inline with deactivateRouterAndItsChildren, namely checking outlet.isActivated before trying to access outlet.component. Fixes angular#39030 PR Close angular#39049
1 parent 5b15e5e commit ea19683

File tree

2 files changed

+18
-3
lines changed

2 files changed

+18
-3
lines changed

packages/router/src/utils/preactivation.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,8 @@ function getRouteGuards(
121121
getChildRouteGuards(futureNode, currNode, parentContexts, futurePath, checks);
122122
}
123123

124-
if (shouldRun) {
125-
const component = context && context.outlet && context.outlet.component || null;
126-
checks.canDeactivateChecks.push(new CanDeactivate(component, curr));
124+
if (shouldRun && context && context.outlet && context.outlet.isActivated) {
125+
checks.canDeactivateChecks.push(new CanDeactivate(context.outlet.component, curr));
127126
}
128127
} else {
129128
if (curr) {

packages/router/test/integration.spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3027,6 +3027,13 @@ describe('Integration', () => {
30273027
resolve: {data: 'resolver'},
30283028
},
30293029
]
3030+
},
3031+
{
3032+
path: 'throwing',
3033+
runGuardsAndResolvers,
3034+
component: ThrowingCmp,
3035+
canActivate: ['guard'],
3036+
resolve: {data: 'resolver'}
30303037
}
30313038
]);
30323039

@@ -3125,6 +3132,15 @@ describe('Integration', () => {
31253132
advance(fixture);
31263133
expect(guardRunCount).toEqual(5);
31273134
expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}, {data: 3}, {data: 4}]);
3135+
3136+
// Issue #39030, always running guards and resolvers should not throw
3137+
// when navigating away from a component with a throwing constructor.
3138+
expect(() => {
3139+
router.navigateByUrl('/throwing').catch(() => {});
3140+
advance(fixture);
3141+
router.navigateByUrl('/a;p=1');
3142+
advance(fixture);
3143+
}).not.toThrow();
31283144
})));
31293145

31303146
it('should rerun rerun guards and resolvers when path params change',

0 commit comments

Comments
 (0)