Skip to content

Commit 232a8c1

Browse files
atscottpkozlowski-opensource
authored andcommitted
fix(router): Apply named outlets to children empty paths not appearing 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
1 parent 8f944e0 commit 232a8c1

File tree

2 files changed

+39
-6
lines changed

2 files changed

+39
-6
lines changed

packages/router/src/create_url_tree.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -338,10 +338,10 @@ function updateSegmentGroupChildren(
338338
} else {
339339
const outlets = getOutlets(commands);
340340
const children: {[key: string]: UrlSegmentGroup} = {};
341-
// If the set of commands does not apply anything to the primary outlet and the child segment is
342-
// an empty path primary segment on its own, we want to apply the commands to the empty child
343-
// path rather than here. The outcome is that the empty primary child is effectively removed
344-
// from the final output UrlTree. Imagine the following config:
341+
// If the set of commands applies to anything other than the primary outlet and the child
342+
// segment is an empty path primary segment on its own, we want to apply the commands to the
343+
// empty child path rather than here. The outcome is that the empty primary child is effectively
344+
// removed from the final output UrlTree. Imagine the following config:
345345
//
346346
// {path: '', children: [{path: '**', outlet: 'popup'}]}.
347347
//
@@ -359,8 +359,8 @@ function updateSegmentGroupChildren(
359359
// `UrlSegmentGroup` that is created from an "unsquashed"/expanded `ActivatedRoute` tree.
360360
// This code effectively "squashes" empty path primary routes when they have no siblings on
361361
// the same level of the tree.
362-
if (!outlets[PRIMARY_OUTLET] && segmentGroup.children[PRIMARY_OUTLET] &&
363-
segmentGroup.numberOfChildren === 1 &&
362+
if (Object.keys(outlets).some(o => o !== PRIMARY_OUTLET) &&
363+
segmentGroup.children[PRIMARY_OUTLET] && segmentGroup.numberOfChildren === 1 &&
364364
segmentGroup.children[PRIMARY_OUTLET].segments.length === 0) {
365365
const childrenOfEmptyChild =
366366
updateSegmentGroupChildren(segmentGroup.children[PRIMARY_OUTLET], startIndex, commands);

packages/router/test/create_url_tree.spec.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,39 @@ describe('createUrlTree', async () => {
231231
.toEqual('/case/(foo:foo)');
232232
});
233233

234+
it('can change both primary and named outlets under an empty path', async () => {
235+
router.resetConfig([{
236+
path: 'foo',
237+
children: [
238+
{
239+
path: '',
240+
component: class {},
241+
children: [
242+
{path: 'bar', component: class {}},
243+
{path: 'baz', component: class {}, outlet: 'other'},
244+
],
245+
},
246+
]
247+
}]);
248+
249+
await router.navigateByUrl('/foo/(bar//other:baz)');
250+
expect(router.url).toEqual('/foo/(bar//other:baz)');
251+
expect(router
252+
.createUrlTree(
253+
[
254+
{
255+
outlets: {
256+
other: null,
257+
primary: ['bar'],
258+
},
259+
},
260+
],
261+
// relative to the root '' route
262+
{relativeTo: router.routerState.root.firstChild})
263+
.toString())
264+
.toEqual('/foo/bar');
265+
});
266+
234267
describe('absolute navigations', () => {
235268
it('with and pathless root', async () => {
236269
router.resetConfig([

0 commit comments

Comments
 (0)