diff --git a/modules/@angular/router/CHANGELOG.md b/modules/@angular/router/CHANGELOG.md index e52f92a16c..b9a0113b50 100644 --- a/modules/@angular/router/CHANGELOG.md +++ b/modules/@angular/router/CHANGELOG.md @@ -7,6 +7,7 @@ ## Bug Fixes * fix(router): stringify positional parameters when using routerLink +* fix(router): change serialize not to require parenthesis in query string to be encoded ## Breaking Changes diff --git a/modules/@angular/router/src/url_serializer.ts b/modules/@angular/router/src/url_serializer.ts index c5c8958667..b6502760e5 100644 --- a/modules/@angular/router/src/url_serializer.ts +++ b/modules/@angular/router/src/url_serializer.ts @@ -115,11 +115,18 @@ function pairs(obj: {[key: string]: T}): Pair[] { const SEGMENT_RE = /^[^\/\(\)\?;=&#]+/; function matchPathWithParams(str: string): string { SEGMENT_RE.lastIndex = 0; - var match = SEGMENT_RE.exec(str); + const match = SEGMENT_RE.exec(str); return match ? match[0] : ''; } -const QUERY_PARAM_VALUE_RE = /^[^\(\)\?;&#]+/; +const QUERY_PARAM_RE = /^[^=\?&#]+/; +function matchQueryParams(str: string): string { + QUERY_PARAM_RE.lastIndex = 0; + const match = SEGMENT_RE.exec(str); + return match ? match[0] : ''; +} + +const QUERY_PARAM_VALUE_RE = /^[^\?&#]+/; function matchUrlQueryParamValue(str: string): string { QUERY_PARAM_VALUE_RE.lastIndex = 0; const match = QUERY_PARAM_VALUE_RE.exec(str); @@ -188,7 +195,7 @@ class UrlParser { } parseQueryParams(): {[key: string]: any} { - var params: {[key: string]: any} = {}; + const params: {[key: string]: any} = {}; if (this.peekStartsWith('?')) { this.capture('?'); this.parseQueryParam(params); @@ -209,7 +216,7 @@ class UrlParser { } parseMatrixParams(): {[key: string]: any} { - var params: {[key: string]: any} = {}; + const params: {[key: string]: any} = {}; while (this.remaining.length > 0 && this.peekStartsWith(';')) { this.capture(';'); this.parseParam(params); @@ -218,15 +225,15 @@ class UrlParser { } parseParam(params: {[key: string]: any}): void { - var key = matchPathWithParams(this.remaining); + const key = matchPathWithParams(this.remaining); if (!key) { return; } this.capture(key); - var value: any = 'true'; + let value: any = 'true'; if (this.peekStartsWith('=')) { this.capture('='); - var valueMatch = matchPathWithParams(this.remaining); + const valueMatch = matchPathWithParams(this.remaining); if (valueMatch) { value = valueMatch; this.capture(value); @@ -237,12 +244,12 @@ class UrlParser { } parseQueryParam(params: {[key: string]: any}): void { - var key = matchPathWithParams(this.remaining); + const key = matchQueryParams(this.remaining); if (!key) { return; } this.capture(key); - var value: any = 'true'; + let value: any = 'true'; if (this.peekStartsWith('=')) { this.capture('='); var valueMatch = matchUrlQueryParamValue(this.remaining); diff --git a/modules/@angular/router/test/url_serializer.spec.ts b/modules/@angular/router/test/url_serializer.spec.ts index 6b780123c5..804212f471 100644 --- a/modules/@angular/router/test/url_serializer.spec.ts +++ b/modules/@angular/router/test/url_serializer.spec.ts @@ -92,6 +92,11 @@ describe('url serializer', () => { expect(tree.queryParams).toEqual({a: '1', b: '2'}); }); + it("should parse query params when with parenthesis", () => { + const tree = url.parse("/one?a=(11)&b=(22)"); + expect(tree.queryParams).toEqual({a: '(11)', b: '(22)'}); + }); + it("should parse key only query params", () => { const tree = url.parse("/one?a"); expect(tree.queryParams).toEqual({a: 'true'});