Skip to content

Commit

Permalink
Allow strings to be split into arrays if desired
Browse files Browse the repository at this point in the history
  • Loading branch information
paul42 authored and ljharb committed Oct 24, 2017
1 parent dadf9db commit 605216b
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 2 deletions.
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,30 @@ assert.deepEqual(detectedAsIso8859_1, { a: '☺' });
It also works when the charset has been detected in `charsetSentinel`
mode.

### Overriding how values are parsed

**qs** can take an optional `valueParser` function as an option - this will parse the value before it is assigned

signature: Function that takes key and val, and returns the desired parsed value. in this example, Key would be `a[]` and value would be `b,c`. the return value is an array of `['b', 'c']`

```javascript
var parseCommaDelimitedString = function (key, val) {
var brackets = /(\[[^[\]]*])/;
var returnVal = val;

if (val !== null
&& brackets.test(key)
&& typeof val === 'string'
&& val.indexOf(',') !== -1)
{
returnVal = val.split(',');
}
return returnVal;
};
var customParsedObject = qs.parse('a[]=b,c', { valueParser: parseCommaDelimitedString })
assert.deepEqual(customParsedObject, { a: ['b', 'c'] })
```

### Parsing Arrays

**qs** can also parse arrays using a similar `[]` notation:
Expand Down
11 changes: 9 additions & 2 deletions lib/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ var parseValues = function parseQueryStringValues(str, options) {
val = interpretNumericEntities(val);
}

if (val && options.comma && val.indexOf(',') > -1) {
if (options.valueParser !== null) {
val = options.valueParser(key, val, options);
} else if (val && options.comma && val.indexOf(',') > -1) {
val = val.split(',');
}

Expand Down Expand Up @@ -200,6 +202,10 @@ var normalizeParseOptions = function normalizeParseOptions(opts) {
}
var charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset;

if (opts.valueParser !== null && opts.valueParser !== undefined && typeof opts.valueParser !== 'function') {
throw new TypeError('valueParser has to be a function.');
}

return {
allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots,
allowPrototypes: typeof opts.allowPrototypes === 'boolean' ? opts.allowPrototypes : defaults.allowPrototypes,
Expand All @@ -216,7 +222,8 @@ var normalizeParseOptions = function normalizeParseOptions(opts) {
parameterLimit: typeof opts.parameterLimit === 'number' ? opts.parameterLimit : defaults.parameterLimit,
parseArrays: opts.parseArrays !== false,
plainObjects: typeof opts.plainObjects === 'boolean' ? opts.plainObjects : defaults.plainObjects,
strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling
strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling,
valueParser: valueParser
};
};

Expand Down
25 changes: 25 additions & 0 deletions test/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,31 @@ test('parse()', function (t) {
st.end();
});

t.test('parses a value with the supplied function', function (st) {
st.deepEqual(qs.parse('a[]=b,c', { valueParser: function (key, val) {
var brackets = /(\[[^[\]]*])/;
var returnVal = val;

if (
val !== null
&& brackets.test(key)
&& typeof val === 'string'
&& val.indexOf(',') !== -1
) {
returnVal = val.split(',');
}
return returnVal;
} }), { a: ['b', 'c'] });
st.end();
});

t.test('throws error with badly crafted valueParser', function (st) {
st['throws'](function () {
qs.parse({}, { valueParser: 'notAFunction' });
}, new TypeError('valueParser has to be a function.'));
st.end();
});

t.test('parses a mix of simple and explicit arrays', function (st) {
st.deepEqual(qs.parse('a=b&a[]=c'), { a: ['b', 'c'] });
st.deepEqual(qs.parse('a[]=b&a=c'), { a: ['b', 'c'] });
Expand Down

0 comments on commit 605216b

Please sign in to comment.