Skip to content

Commit

Permalink
fix(router): Apply named outlets to children empty paths not appearin…
Browse files Browse the repository at this point in the history
…g in the URL (#51292)

Empty path routes are effectively 'passthrough' routes that do not
appear in the URL. When these exist in the route tree, we do not want to
apply named outlet commands to that tree location. Instead, we skip past
this location in the tree, effectively squashing/removing this
passthrough route from the tree.

fixes #50356

PR Close #51292
  • Loading branch information
atscott authored and pkozlowski-opensource committed Aug 10, 2023
1 parent 8f944e0 commit 232a8c1
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 6 deletions.
12 changes: 6 additions & 6 deletions packages/router/src/create_url_tree.ts
Expand Up @@ -338,10 +338,10 @@ function updateSegmentGroupChildren(
} else {
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 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:
// If the set of commands applies to anything other than the primary outlet and the child
// segment is 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'}]}.
//
Expand All @@ -359,8 +359,8 @@ function updateSegmentGroupChildren(
// `UrlSegmentGroup` that is created from an "unsquashed"/expanded `ActivatedRoute` tree.
// This code effectively "squashes" empty path primary routes when they have no siblings on
// the same level of the tree.
if (!outlets[PRIMARY_OUTLET] && segmentGroup.children[PRIMARY_OUTLET] &&
segmentGroup.numberOfChildren === 1 &&
if (Object.keys(outlets).some(o => o !== PRIMARY_OUTLET) &&
segmentGroup.children[PRIMARY_OUTLET] && segmentGroup.numberOfChildren === 1 &&
segmentGroup.children[PRIMARY_OUTLET].segments.length === 0) {
const childrenOfEmptyChild =
updateSegmentGroupChildren(segmentGroup.children[PRIMARY_OUTLET], startIndex, commands);
Expand Down
33 changes: 33 additions & 0 deletions packages/router/test/create_url_tree.spec.ts
Expand Up @@ -231,6 +231,39 @@ describe('createUrlTree', async () => {
.toEqual('/case/(foo:foo)');
});

it('can change both primary and named outlets under an empty path', async () => {
router.resetConfig([{
path: 'foo',
children: [
{
path: '',
component: class {},
children: [
{path: 'bar', component: class {}},
{path: 'baz', component: class {}, outlet: 'other'},
],
},
]
}]);

await router.navigateByUrl('/foo/(bar//other:baz)');
expect(router.url).toEqual('/foo/(bar//other:baz)');
expect(router
.createUrlTree(
[
{
outlets: {
other: null,
primary: ['bar'],
},
},
],
// relative to the root '' route
{relativeTo: router.routerState.root.firstChild})
.toString())
.toEqual('/foo/bar');
});

describe('absolute navigations', () => {
it('with and pathless root', async () => {
router.resetConfig([
Expand Down

0 comments on commit 232a8c1

Please sign in to comment.