fix(router): add support for query params with mulitple values

closes #11373
This commit is contained in:
Andy Howell 2016-09-06 12:39:53 +01:00 committed by Victor Berchet
parent 4e3d58a792
commit 440ef02f29
2 changed files with 30 additions and 4 deletions

View File

@ -370,9 +370,14 @@ function serializeParams(params: {[key: string]: string}): string {
return pairs(params).map(p => `;${encode(p.first)}=${encode(p.second)}`).join(''); return pairs(params).map(p => `;${encode(p.first)}=${encode(p.second)}`).join('');
} }
function serializeQueryParams(params: {[key: string]: string}): string { function serializeQueryParams(params: {[key: string]: any}): string {
const strs = pairs(params).map(p => `${encode(p.first)}=${encode(p.second)}`); const strParams: string[] = Object.keys(params).map((name) => {
return strs.length > 0 ? `?${strs.join("&")}` : ''; const value = params[name];
return Array.isArray(value) ? value.map(v => `${encode(name)}=${encode(v)}`).join('&') :
`${encode(name)}=${encode(value)}`;
});
return strParams.length ? `?${strParams.join("&")}` : '';
} }
class Pair<A, B> { class Pair<A, B> {
@ -534,6 +539,7 @@ class UrlParser {
params[decode(key)] = decode(value); params[decode(key)] = decode(value);
} }
// Parse a single query parameter `name[=value]`
parseQueryParam(params: {[key: string]: any}): void { parseQueryParam(params: {[key: string]: any}): void {
const key = matchQueryParams(this.remaining); const key = matchQueryParams(this.remaining);
if (!key) { if (!key) {
@ -549,7 +555,22 @@ class UrlParser {
this.capture(value); this.capture(value);
} }
} }
params[decode(key)] = decode(value);
const decodedKey = decode(key);
const decodedVal = decode(value);
if (params.hasOwnProperty(decodedKey)) {
// Append to existing values
let currentVal = params[decodedKey];
if (!Array.isArray(currentVal)) {
currentVal = [currentVal];
params[decodedKey] = currentVal;
}
currentVal.push(decodedVal);
} else {
// Create a new value
params[decodedKey] = decodedVal;
}
} }
parseParens(allowPrimary: boolean): {[key: string]: UrlSegmentGroup} { parseParens(allowPrimary: boolean): {[key: string]: UrlSegmentGroup} {

View File

@ -160,6 +160,11 @@ describe('url serializer', () => {
expect(url.serialize(tree)).toEqual('/one?a='); expect(url.serialize(tree)).toEqual('/one?a=');
}); });
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']});
});
it('should parse fragment', () => { it('should parse fragment', () => {
const tree = url.parse('/one#two'); const tree = url.parse('/one#two');
expect(tree.fragment).toEqual('two'); expect(tree.fragment).toEqual('two');