Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

feature(urlKeyValue): not rewriting duplicate params in url #2522

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions src/Angular.js
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,14 @@ function parseKeyValue(/**string*/keyValue) {
if (keyValue) {
key_value = keyValue.split('=');
key = decodeURIComponent(key_value[0]);
obj[key] = isDefined(key_value[1]) ? decodeURIComponent(key_value[1]) : true;
var val = isDefined(key_value[1]) ? decodeURIComponent(key_value[1]) : true;
if (!obj[key]) {
obj[key] = val;
} else if(isArray(obj[key])) {
obj[key].push(val);
} else {
obj[key] = [obj[key],val];
}
}
});
return obj;
Expand All @@ -836,7 +843,13 @@ function parseKeyValue(/**string*/keyValue) {
function toKeyValue(obj) {
var parts = [];
forEach(obj, function(value, key) {
parts.push(encodeUriQuery(key, true) + (value === true ? '' : '=' + encodeUriQuery(value, true)));
if (isArray(value)) {
forEach(value, function(arrayValue) {
parts.push(encodeUriQuery(key, true) + (arrayValue === true ? '' : '=' + encodeUriQuery(arrayValue, true)));
});
} else {
parts.push(encodeUriQuery(key, true) + (value === true ? '' : '=' + encodeUriQuery(value, true)));
}
});
return parts.length ? parts.join('&') : '';
}
Expand Down
3 changes: 2 additions & 1 deletion src/ng/location.js
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,8 @@ LocationHashbangInHtml5Url.prototype =
*
* Change search part when called with parameter and return `$location`.
*
* @param {string|object<string,string>=} search New search params - string or hash object
* @param {string|Object.<string>|Object.<Array.<string>>} search New search params - string or hash object. Hash object
* may contain an array of values, which will be decoded as duplicates in the url.
* @param {string=} paramValue If `search` is a string, then `paramValue` will override only a
* single search parameter. If the value is `null`, the parameter will be deleted.
*
Expand Down
22 changes: 20 additions & 2 deletions test/AngularSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,10 +253,22 @@ describe('angular', function() {
expect(parseKeyValue('flag1&key=value&flag2')).
toEqual({flag1: true, key: 'value', flag2: true});
});

it('should parse a string into key-value pairs with duplicates grouped in an array', function() {
expect(parseKeyValue('')).toEqual({});
expect(parseKeyValue('duplicate=pair')).toEqual({duplicate: 'pair'});
expect(parseKeyValue('first=1&first=2')).toEqual({first: ['1','2']});
expect(parseKeyValue('escaped%20key=escaped%20value&&escaped%20key=escaped%20value2')).
toEqual({'escaped key': ['escaped value','escaped value2']});
expect(parseKeyValue('flag1&key=value&flag1')).
toEqual({flag1: [true,true], key: 'value'});
expect(parseKeyValue('flag1&flag1=value&flag1=value2&flag1')).
toEqual({flag1: [true,'value','value2',true]});
});
});

describe('toKeyValue', function() {
it('should parse key-value pairs into string', function() {
it('should serialize key-value pairs into string', function() {
expect(toKeyValue({})).toEqual('');
expect(toKeyValue({simple: 'pair'})).toEqual('simple=pair');
expect(toKeyValue({first: '1', second: '2'})).toEqual('first=1&second=2');
Expand All @@ -265,9 +277,15 @@ describe('angular', function() {
expect(toKeyValue({emptyKey: ''})).toEqual('emptyKey=');
});

it('should parse true values into flags', function() {
it('should serialize true values into flags', function() {
expect(toKeyValue({flag1: true, key: 'value', flag2: true})).toEqual('flag1&key=value&flag2');
});

it('should serialize duplicates into duplicate param strings', function() {
expect(toKeyValue({key: [323,'value',true]})).toEqual('key=323&key=value&key');
expect(toKeyValue({key: [323,'value',true, 1234]})).
toEqual('key=323&key=value&key&key=1234');
});
});


Expand Down
23 changes: 23 additions & 0 deletions test/ng/locationSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,29 @@ describe('$location', function() {
locationUrl.search('q', '1/2 3');
expect(locationUrl.search()).toEqual({'q': '1/2 3'});
});

it('should return an array for duplicate params', function() {
var locationUrl = new LocationHtml5Url('http://host.com');
locationUrl.$$parse('http://host.com')
locationUrl.search('q', ['1/2 3','4/5 6']);
expect(locationUrl.search()).toEqual({'q': ['1/2 3','4/5 6']});
});

it('should encode an array correctly from search and add to url', function() {
var locationUrl = new LocationHtml5Url('http://host.com');
locationUrl.$$parse('http://host.com')
locationUrl.search({'q': ['1/2 3','4/5 6']});
expect(locationUrl.absUrl()).toEqual('http://host.com?q=1%2F2%203&q=4%2F5%206');
});

it('should rewrite params when specifing a single param in search', function() {
var locationUrl = new LocationHtml5Url('http://host.com');
locationUrl.$$parse('http://host.com')
locationUrl.search({'q': '1/2 3'});
expect(locationUrl.absUrl()).toEqual('http://host.com?q=1%2F2%203');
locationUrl.search({'q': '4/5 6'});
expect(locationUrl.absUrl()).toEqual('http://host.com?q=4%2F5%206');
});
});
});

Expand Down