diff options
| author | joshkurz | 2013-04-26 17:31:56 -0400 |
|---|---|---|
| committer | Pete Bacon Darwin | 2013-07-01 19:32:12 +0100 |
| commit | 807394095b991357225a03d5fed81fea5c9a1abe (patch) | |
| tree | 5e2d1a6eb337f2fcb7dfc7a7bc76a271f6ae7af5 /src | |
| parent | a258817310e83ae58a0ce95226e77a9f151d7197 (diff) | |
| download | angular.js-807394095b991357225a03d5fed81fea5c9a1abe.tar.bz2 | |
fix(Angular.js): handle duplicate params in parseKeyValue/toKeyValue
parseKeyValue and toKeyValue can now handle duplicate values in the query.
```
?x=1&x=2 <-> {x:[1,2]}
```
The algorithm looks like:
1)parseKeyValue looks for presence of obj[key]
2)detects and replaces obj[key] with [obj[key],val]
3)then pushes more duplicates if necessary
4)toKeyValue decodes array correctly
5)(not changed)$location.search({param: 'key'}) still replaces if necessary
6)(not changed)$location.search({param: ['key1', 'key2']}) sets the url with duplicates
BREAKING CHANGE: Before this change:
- `parseKeyValue` only took the last key overwriting all the previous keys;
- `toKeyValue` joined the keys together in a comma delimited string.
This was deemed buggy behavior. If your server relied on this behavior
then either the server should be fixed or a simple serialization of
the array should be done on the client before passing it to $location.
Diffstat (limited to 'src')
| -rw-r--r-- | src/Angular.js | 15 | ||||
| -rw-r--r-- | src/ng/location.js | 3 |
2 files changed, 16 insertions, 2 deletions
diff --git a/src/Angular.js b/src/Angular.js index 5caf4665..c1066618 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -850,7 +850,14 @@ function parseKeyValue(/**string*/keyValue) { key_value = keyValue.split('='); key = tryDecodeURIComponent(key_value[0]); if ( isDefined(key) ) { - obj[key] = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true; + var val = isDefined(key_value[1]) ? tryDecodeURIComponent(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]; + } } } }); @@ -860,7 +867,13 @@ function parseKeyValue(/**string*/keyValue) { function toKeyValue(obj) { var parts = []; forEach(obj, function(value, key) { + 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('&') : ''; } diff --git a/src/ng/location.js b/src/ng/location.js index 40d39282..a0f03a8e 100644 --- a/src/ng/location.js +++ b/src/ng/location.js @@ -344,7 +344,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. * |
