From 61a44f4653de1284ce8ebc18ee81bbd5a816a26d Mon Sep 17 00:00:00 2001 From: Julian Gonggrijp Date: Sat, 29 Aug 2020 15:28:59 +0200 Subject: [PATCH 1/4] Add a test to reproduce #217 --- test/util.strings.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/util.strings.js b/test/util.strings.js index c7c0b10..2ffdc6d 100644 --- a/test/util.strings.js +++ b/test/util.strings.js @@ -43,6 +43,8 @@ $(document).ready(function() { var obj = {'foo&bar': 'baz', 'test': 'total success', 'nested': {'works': 'too'}, 'isn\'t': ['that', 'cool?']}; assert.equal(_.toQuery(obj), 'foo%26bar=baz&test=total%20success&nested%5Bworks%5D=too&isn\'t%5B%5D=that&isn\'t%5B%5D=cool%3F', 'can convert a hash to a query string'); assert.equal(_.toQuery(obj), jQuery.param(obj), 'query serialization matchs jQuery.param()'); + assert.equal(_.toQuery({a: []}), '', 'empty array params produce the empty string'); + assert.equal(_.toQuery({a: [], b: []}), '', 'multiple empty array params do not lead to spurious ampersands'); }); QUnit.test('strContains', function(assert) { From 8eaa5dcd36fddb807fa3977d58dccc258655a466 Mon Sep 17 00:00:00 2001 From: Julian Gonggrijp Date: Sat, 29 Aug 2020 15:32:21 +0200 Subject: [PATCH 2/4] Remove empty query substrings before concatenating (fix #217) --- underscore.util.strings.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/underscore.util.strings.js b/underscore.util.strings.js index b7384c1..a1b97dd 100644 --- a/underscore.util.strings.js +++ b/underscore.util.strings.js @@ -33,9 +33,9 @@ return buildParams(top ? key : prefix + '[]', value, false); }).join('&'); } else if (_.isObject(val)) { - return _.map(val, function(value, key) { + return _.compact(_.map(val, function(value, key) { return buildParams(top ? key : prefix + '[' + key + ']', value, false); - }).join('&'); + })).join('&'); } else { return urlEncode(prefix) + '=' + urlEncode(val); } From f83c293386808c3a9198c4186d01037616ae3068 Mon Sep 17 00:00:00 2001 From: Julian Gonggrijp Date: Sun, 30 Aug 2020 14:10:27 +0200 Subject: [PATCH 3/4] Test against null and undefined after a comment by @carpben (#217) --- test/util.strings.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/util.strings.js b/test/util.strings.js index 2ffdc6d..a88c5e3 100644 --- a/test/util.strings.js +++ b/test/util.strings.js @@ -45,6 +45,7 @@ $(document).ready(function() { assert.equal(_.toQuery(obj), jQuery.param(obj), 'query serialization matchs jQuery.param()'); assert.equal(_.toQuery({a: []}), '', 'empty array params produce the empty string'); assert.equal(_.toQuery({a: [], b: []}), '', 'multiple empty array params do not lead to spurious ampersands'); + assert.equal(_.toQuery({a: null, b: undefined}), 'a=null&b=undefined', 'respects null and undefined'); }); QUnit.test('strContains', function(assert) { From dc0b5534e59694b798b2e39cefcd73f74beb4590 Mon Sep 17 00:00:00 2001 From: Julian Gonggrijp Date: Sun, 30 Aug 2020 14:11:46 +0200 Subject: [PATCH 4/4] Filter empty strings from array recursion as well (#217) After a comment by @carpben. --- underscore.util.strings.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/underscore.util.strings.js b/underscore.util.strings.js index a1b97dd..291c26a 100644 --- a/underscore.util.strings.js +++ b/underscore.util.strings.js @@ -29,9 +29,9 @@ var buildParams = function(prefix, val, top) { if (_.isUndefined(top)) top = true; if (_.isArray(val)) { - return _.map(val, function(value, key) { + return _.compact(_.map(val, function(value, key) { return buildParams(top ? key : prefix + '[]', value, false); - }).join('&'); + })).join('&'); } else if (_.isObject(val)) { return _.compact(_.map(val, function(value, key) { return buildParams(top ? key : prefix + '[' + key + ']', value, false);