fix(router): create correct URL relative to path with empty child (#49691)

The previous fix for squashing empty children didn't quite work when the
existing route had segments. The result would be that the segments from
the existing route were dropped from the final URL.

PR Close #49691
This commit is contained in:
Andrew Scott 2023-04-03 13:49:45 -07:00 committed by Dylan Hunn
parent a218ef5bf2
commit b203e4c19d
2 changed files with 32 additions and 4 deletions

View file

@ -339,8 +339,9 @@ function updateSegmentGroupChildren(
const outlets = getOutlets(commands);
const children: {[key: string]: UrlSegmentGroup} = {};
// If the set of commands does not apply anything to the primary outlet and the child segment is
// an empty path primary segment on its own, we want to skip applying the commands at this
// level. Imagine the following config:
// an empty path primary segment on its own, we want to apply the commands to the empty child
// path rather than here. The outcome is that the empty primary child is effectively removed
// from the final output UrlTree. Imagine the following config:
//
// {path: '', children: [{path: '**', outlet: 'popup'}]}.
//
@ -361,8 +362,9 @@ function updateSegmentGroupChildren(
if (!outlets[PRIMARY_OUTLET] && segmentGroup.children[PRIMARY_OUTLET] &&
segmentGroup.numberOfChildren === 1 &&
segmentGroup.children[PRIMARY_OUTLET].segments.length === 0) {
return updateSegmentGroupChildren(
segmentGroup.children[PRIMARY_OUTLET], startIndex, commands);
const childrenOfEmptyChild =
updateSegmentGroupChildren(segmentGroup.children[PRIMARY_OUTLET], startIndex, commands);
return new UrlSegmentGroup(segmentGroup.segments, childrenOfEmptyChild.children);
}
Object.entries(outlets).forEach(([outlet, commands]) => {

View file

@ -206,6 +206,32 @@ describe('createUrlTree', async () => {
expect(serializer.serialize(t)).toEqual('/parent/child(rootSecondary:rootPopup)');
});
it('works with named children of empty path primary, relative to non-empty parent',
async () => {
router.resetConfig([{
path: 'case',
component: class {},
children: [
{
path: '',
component: class {},
children: [
{path: 'foo', outlet: 'foo', children: []},
],
},
]
}]);
await router.navigateByUrl('/case');
expect(router.url).toEqual('/case');
expect(router
.createUrlTree(
[{outlets: {'foo': ['foo']}}],
// relative to the 'case' route
{relativeTo: router.routerState.root.firstChild})
.toString())
.toEqual('/case/(foo:foo)');
});
describe('absolute navigations', () => {
it('with and pathless root', async () => {
router.resetConfig([