From 029d0f25e529954e7840f3a55c554a8456bc0d57 Mon Sep 17 00:00:00 2001 From: Victor Berchet Date: Wed, 15 Mar 2017 15:27:19 -0700 Subject: [PATCH] fix(router): fix query parameters with multiple values (#15129) fixes #14796 --- packages/router/src/create_url_tree.ts | 15 +++++--- packages/router/test/create_url_tree.spec.ts | 36 +++++++++++++------- packages/router/test/url_serializer.spec.ts | 1 + 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/packages/router/src/create_url_tree.ts b/packages/router/src/create_url_tree.ts index 91ae21072c..ab0d3e6bb5 100644 --- a/packages/router/src/create_url_tree.ts +++ b/packages/router/src/create_url_tree.ts @@ -40,13 +40,18 @@ function isMatrixParams(command: any): boolean { function tree( oldSegmentGroup: UrlSegmentGroup, newSegmentGroup: UrlSegmentGroup, urlTree: UrlTree, queryParams: Params, fragment: string): UrlTree { - if (urlTree.root === oldSegmentGroup) { - return new UrlTree(newSegmentGroup, stringify(queryParams), fragment); + let qp: any = {}; + if (queryParams) { + forEach(queryParams, (value: any, name: any) => { + qp[name] = Array.isArray(value) ? value.map((v: any) => `${v}`) : `${value}`; + }); } - return new UrlTree( - replaceSegment(urlTree.root, oldSegmentGroup, newSegmentGroup), stringify(queryParams), - fragment); + if (urlTree.root === oldSegmentGroup) { + return new UrlTree(newSegmentGroup, qp, fragment); + } + + return new UrlTree(replaceSegment(urlTree.root, oldSegmentGroup, newSegmentGroup), qp, fragment); } function replaceSegment( diff --git a/packages/router/test/create_url_tree.spec.ts b/packages/router/test/create_url_tree.spec.ts index 7482c6ec45..0e40e875e5 100644 --- a/packages/router/test/create_url_tree.spec.ts +++ b/packages/router/test/create_url_tree.spec.ts @@ -16,6 +16,30 @@ import {DefaultUrlSerializer, UrlSegmentGroup, UrlTree} from '../src/url_tree'; describe('createUrlTree', () => { const serializer = new DefaultUrlSerializer(); + describe('query parameters', () => { + it('should support parameter with multiple values', () => { + const p1 = serializer.parse('/'); + const t1 = createRoot(p1, ['/'], {m: ['v1', 'v2']}); + expect(serializer.serialize(t1)).toEqual('/?m=v1&m=v2'); + + const p2 = serializer.parse('/a/c'); + const t2 = create(p2.root.children[PRIMARY_OUTLET], 1, p2, ['c2'], {m: ['v1', 'v2']}); + expect(serializer.serialize(t2)).toEqual('/a/c/c2?m=v1&m=v2'); + }); + + it('should set query params', () => { + const p = serializer.parse('/'); + const t = createRoot(p, [], {a: 'hey'}); + expect(t.queryParams).toEqual({a: 'hey'}); + }); + + it('should stringify query params', () => { + const p = serializer.parse('/'); + const t = createRoot(p, [], {a: 1}); + expect(t.queryParams).toEqual({a: '1'}); + }); + }); + it('should navigate to the root', () => { const p = serializer.parse('/'); const t = createRoot(p, ['/']); @@ -209,18 +233,6 @@ describe('createUrlTree', () => { }); }); - it('should set query params', () => { - const p = serializer.parse('/'); - const t = createRoot(p, [], {a: 'hey'}); - expect(t.queryParams).toEqual({a: 'hey'}); - }); - - it('should stringify query params', () => { - const p = serializer.parse('/'); - const t = createRoot(p, [], {a: 1}); - expect(t.queryParams).toEqual({a: '1'}); - }); - it('should set fragment', () => { const p = serializer.parse('/'); const t = createRoot(p, [], {}, 'fragment'); diff --git a/packages/router/test/url_serializer.spec.ts b/packages/router/test/url_serializer.spec.ts index abf426d91b..3ea8a18414 100644 --- a/packages/router/test/url_serializer.spec.ts +++ b/packages/router/test/url_serializer.spec.ts @@ -163,6 +163,7 @@ describe('url serializer', () => { it('should handle multiple query params of the same name into an array', () => { const tree = url.parse('/one?a=foo&a=bar&a=swaz'); expect(tree.queryParams).toEqual({a: ['foo', 'bar', 'swaz']}); + expect(url.serialize(tree)).toEqual('/one?a=foo&a=bar&a=swaz'); }); it('should parse fragment', () => {