fix(router): update getRouteGuards to check if the context outlet is activated (#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 #39030 PR Close #39049
This commit is contained in:
parent
5b15e5eeae
commit
ea1968317e
|
@ -121,9 +121,8 @@ function getRouteGuards(
|
||||||
getChildRouteGuards(futureNode, currNode, parentContexts, futurePath, checks);
|
getChildRouteGuards(futureNode, currNode, parentContexts, futurePath, checks);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldRun) {
|
if (shouldRun && context && context.outlet && context.outlet.isActivated) {
|
||||||
const component = context && context.outlet && context.outlet.component || null;
|
checks.canDeactivateChecks.push(new CanDeactivate(context.outlet.component, curr));
|
||||||
checks.canDeactivateChecks.push(new CanDeactivate(component, curr));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (curr) {
|
if (curr) {
|
||||||
|
|
|
@ -3027,6 +3027,13 @@ describe('Integration', () => {
|
||||||
resolve: {data: 'resolver'},
|
resolve: {data: 'resolver'},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'throwing',
|
||||||
|
runGuardsAndResolvers,
|
||||||
|
component: ThrowingCmp,
|
||||||
|
canActivate: ['guard'],
|
||||||
|
resolve: {data: 'resolver'}
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -3125,6 +3132,15 @@ describe('Integration', () => {
|
||||||
advance(fixture);
|
advance(fixture);
|
||||||
expect(guardRunCount).toEqual(5);
|
expect(guardRunCount).toEqual(5);
|
||||||
expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}, {data: 3}, {data: 4}]);
|
expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}, {data: 3}, {data: 4}]);
|
||||||
|
|
||||||
|
// Issue #39030, always running guards and resolvers should not throw
|
||||||
|
// when navigating away from a component with a throwing constructor.
|
||||||
|
expect(() => {
|
||||||
|
router.navigateByUrl('/throwing').catch(() => {});
|
||||||
|
advance(fixture);
|
||||||
|
router.navigateByUrl('/a;p=1');
|
||||||
|
advance(fixture);
|
||||||
|
}).not.toThrow();
|
||||||
})));
|
})));
|
||||||
|
|
||||||
it('should rerun rerun guards and resolvers when path params change',
|
it('should rerun rerun guards and resolvers when path params change',
|
||||||
|
|
Loading…
Reference in New Issue