Skip to content

Commit 9c46a95

Browse files
committed
Add arrayFormat option
This commit adds the arrayFormat option to qs.stringify. Valid values are "indices" (the default), "repeat", or "brackets". Backwards compat is preserved with the indices option as well.
1 parent 9250c4c commit 9c46a95

File tree

2 files changed

+59
-9
lines changed

2 files changed

+59
-9
lines changed

lib/stringify.js

+29-9
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,21 @@ var Utils = require('./utils');
77

88
var internals = {
99
delimiter: '&',
10-
indices: true
10+
arrayPrefixGenerators: {
11+
brackets: function (prefix, key) {
12+
return prefix + '[]';
13+
},
14+
indices: function (prefix, key) {
15+
return prefix + '[' + key + ']';
16+
},
17+
repeat: function (prefix, key) {
18+
return prefix;
19+
}
20+
}
1121
};
1222

1323

14-
internals.stringify = function (obj, prefix, options) {
24+
internals.stringify = function (obj, prefix, generateArrayPrefix) {
1525

1626
if (Utils.isBuffer(obj)) {
1727
obj = obj.toString();
@@ -39,13 +49,11 @@ internals.stringify = function (obj, prefix, options) {
3949
var objKeys = Object.keys(obj);
4050
for (var i = 0, il = objKeys.length; i < il; ++i) {
4151
var key = objKeys[i];
42-
if (!options.indices &&
43-
Array.isArray(obj)) {
44-
45-
values = values.concat(internals.stringify(obj[key], prefix, options));
52+
if (Array.isArray(obj)) {
53+
values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix));
4654
}
4755
else {
48-
values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', options));
56+
values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix));
4957
}
5058
}
5159

@@ -57,7 +65,6 @@ module.exports = function (obj, options) {
5765

5866
options = options || {};
5967
var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter;
60-
options.indices = typeof options.indices === 'boolean' ? options.indices : internals.indices;
6168

6269
var keys = [];
6370

@@ -67,10 +74,23 @@ module.exports = function (obj, options) {
6774
return '';
6875
}
6976

77+
var arrayFormat;
78+
if (options.arrayFormat in internals.arrayPrefixGenerators) {
79+
arrayFormat = options.arrayFormat;
80+
}
81+
else if ('indices' in options) {
82+
arrayFormat = options.indices ? 'indices' : 'repeat';
83+
}
84+
else {
85+
arrayFormat = 'indices';
86+
}
87+
88+
var generateArrayPrefix = internals.arrayPrefixGenerators[arrayFormat];
89+
7090
var objKeys = Object.keys(obj);
7191
for (var i = 0, il = objKeys.length; i < il; ++i) {
7292
var key = objKeys[i];
73-
keys = keys.concat(internals.stringify(obj[key], key, options));
93+
keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix));
7494
}
7595

7696
return keys.join(delimiter);

test/stringify.js

+30
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,36 @@ describe('stringify()', function () {
6767
done();
6868
});
6969

70+
it('uses indices notation for arrays when indices=true', function (done) {
71+
72+
expect(Qs.stringify({ a: ['b', 'c'] }, { indices: true })).to.equal('a%5B0%5D=b&a%5B1%5D=c');
73+
done();
74+
});
75+
76+
it('uses indices notation for arrays when no arrayFormat is specified', function (done) {
77+
78+
expect(Qs.stringify({ a: ['b', 'c'] })).to.equal('a%5B0%5D=b&a%5B1%5D=c');
79+
done();
80+
});
81+
82+
it('uses indices notation for arrays when no arrayFormat=indices', function (done) {
83+
84+
expect(Qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' })).to.equal('a%5B0%5D=b&a%5B1%5D=c');
85+
done();
86+
});
87+
88+
it('uses repeat notation for arrays when no arrayFormat=repeat', function (done) {
89+
90+
expect(Qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' })).to.equal('a=b&a=c');
91+
done();
92+
});
93+
94+
it('uses brackets notation for arrays when no arrayFormat=brackets', function (done) {
95+
96+
expect(Qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' })).to.equal('a%5B%5D=b&a%5B%5D=c');
97+
done();
98+
});
99+
70100
it('stringifies a complicated object', function (done) {
71101

72102
expect(Qs.stringify({ a: { b: 'c', d: 'e' } })).to.equal('a%5Bb%5D=c&a%5Bd%5D=e');

0 commit comments

Comments
 (0)