diff --git a/modules/@angular/router/src/url_serializer.ts b/modules/@angular/router/src/url_serializer.ts index b6502760e5..62ebad2405 100644 --- a/modules/@angular/router/src/url_serializer.ts +++ b/modules/@angular/router/src/url_serializer.ts @@ -1,5 +1,5 @@ import {PRIMARY_OUTLET} from './shared'; -import {UrlPathWithParams, UrlSegment, UrlTree} from './url_tree'; +import {UrlPathWithParams, UrlSegment, UrlTree, mapChildrenIntoArray} from './url_tree'; import {forEach} from './utils/collection'; @@ -54,38 +54,22 @@ function serializeSegment(segment: UrlSegment, root: boolean): string { } else { return `${primary}`; } - } else if (segment.children[PRIMARY_OUTLET] && !root) { - const children = [serializeSegment(segment.children[PRIMARY_OUTLET], false)]; - forEach(segment.children, (v: UrlSegment, k: string) => { - if (k !== PRIMARY_OUTLET) { - children.push(`${k}:${serializeSegment(v, false)}`); + + } else if (segment.hasChildren() && !root) { + const children = mapChildrenIntoArray(segment, (v: UrlSegment, k: string) => { + if (k === PRIMARY_OUTLET) { + return [serializeSegment(segment.children[PRIMARY_OUTLET], false)]; + } else { + return [`${k}:${serializeSegment(v, false)}`]; } }); return `${serializePaths(segment)}/(${children.join('//')})`; + } else { return serializePaths(segment); } } -function serializeChildren(segment: UrlSegment) { - if (segment.children[PRIMARY_OUTLET]) { - const primary = serializePaths(segment.children[PRIMARY_OUTLET]); - - const secondary: string[] = []; - forEach(segment.children, (v: UrlSegment, k: string) => { - if (k !== PRIMARY_OUTLET) { - secondary.push(`${k}:${serializePaths(v)}${serializeChildren(v)}`); - } - }); - const secondaryStr = secondary.length > 0 ? `(${secondary.join('//')})` : ''; - const primaryChildren = serializeChildren(segment.children[PRIMARY_OUTLET]); - const primaryChildrenStr: string = primaryChildren ? `/${primaryChildren}` : ''; - return `${primary}${secondaryStr}${primaryChildrenStr}`; - } else { - return ''; - } -} - export function serializePath(path: UrlPathWithParams): string { return `${path.path}${serializeParams(path.parameters)}`; } diff --git a/modules/@angular/router/src/url_tree.ts b/modules/@angular/router/src/url_tree.ts index 9cb4a7b711..9188a73943 100644 --- a/modules/@angular/router/src/url_tree.ts +++ b/modules/@angular/router/src/url_tree.ts @@ -74,6 +74,8 @@ export class UrlSegment { forEach(children, (v: any, k: any) => v.parent = this); } + hasChildren(): boolean { return Object.keys(this.children).length > 0; } + toString(): string { return serializePaths(this); } } diff --git a/modules/@angular/router/test/url_serializer.spec.ts b/modules/@angular/router/test/url_serializer.spec.ts index 804212f471..dcf88e30fa 100644 --- a/modules/@angular/router/test/url_serializer.spec.ts +++ b/modules/@angular/router/test/url_serializer.spec.ts @@ -28,6 +28,33 @@ describe('url serializer', () => { expect(url.serialize(tree)).toEqual("/one/two(left:three//right:four)"); }); + it("should parse segments with empty paths", () => { + const tree = url.parse("/one/two/(;a=1//right:;b=2)"); + + const c = tree.root.children[PRIMARY_OUTLET]; + expectSegment(tree.root.children[PRIMARY_OUTLET], "one/two", true); + + expect(c.children[PRIMARY_OUTLET].pathsWithParams[0].path).toEqual(''); + expect(c.children[PRIMARY_OUTLET].pathsWithParams[0].parameters).toEqual({a: '1'}); + + expect(c.children['right'].pathsWithParams[0].path).toEqual(''); + expect(c.children['right'].pathsWithParams[0].parameters).toEqual({b: '2'}); + + expect(url.serialize(tree)).toEqual("/one/two/(;a=1//right:;b=2)"); + }); + + it("should parse segments with empty paths (only aux)", () => { + const tree = url.parse("/one/two/(right:;b=2)"); + + const c = tree.root.children[PRIMARY_OUTLET]; + expectSegment(tree.root.children[PRIMARY_OUTLET], "one/two", true); + + expect(c.children['right'].pathsWithParams[0].path).toEqual(''); + expect(c.children['right'].pathsWithParams[0].parameters).toEqual({b: '2'}); + + expect(url.serialize(tree)).toEqual("/one/two/(right:;b=2)"); + }); + it("should parse scoped secondary segments", () => { const tree = url.parse("/one/(two//left:three)");