Skip to content

Instantly share code, notes, and snippets.

@samueleiche
Last active December 6, 2019 20:45
Show Gist options
  • Save samueleiche/f665da6993845e84e8dc4144c1bb1f85 to your computer and use it in GitHub Desktop.
Save samueleiche/f665da6993845e84e8dc4144c1bb1f85 to your computer and use it in GitHub Desktop.
JS parse query string/serialize object - Supports arrays - Working example - https://codepen.io/Samuel87/pen/QWWZopj
/**
* Parses a serialized query string to an object
*
* @param {string} query - query string to parse
* @returns {Object}
* @example
* parse('a=b&c=d');
* // => { a: 'b', c: 'd' }
* @example
* parse('a[]=b&a[]=c');
* // => { a: ['b', 'c'] }
*/
const parse = (query) => {
if (!query || Object.prototype.toString.call(query) !== '[object String]') return {};
const hashes = query.slice(query).split('&');
return hashes.reduce((params, hash) => {
const split = hash.indexOf('=');
// If no `=` or nothing after it
if (split < 0 || split >= hash.length - 1) {
const key = hash.replace(/\=/g, '');
return Object.assign(
params,
{
[key]: null,
}
);
}
const key = decodeURIComponent(hash.slice(0, split));
let val = decodeURIComponent(hash.slice(split + 1).replace(/\+/g, ' '));
// Coercions for int and bool
if (!isNaN(+val)) val = +val;
if (val === 'true' || val === 'false') val = val === 'true';
// Array query should have `[]` in key
const isArr = key.indexOf('[]') !== -1;
const keyName = key.replace('[]', '');
if (params.hasOwnProperty(keyName)) {
params[keyName].push(val);
return params;
}
return Object.assign(
params,
{
[keyName]: isArr ? [val] : val
}
);
}, {});
};
/**
* Serializes an object to a query string
*
* @param {Object} obj - object to serialize
* @returns {string}
* @example
* serialize({ a: 'b', c: 'd' });
* // => 'a=b&c=d'
* @example
* serialize({ a: ['b', 'c'] });
* // => 'a[]=b&a[]=c'
*/
const serialize = (obj) => {
if (Object.prototype.toString.call(obj) !== '[object Object]') return '';
return Object.keys(obj).map((key) => {
const val = obj[key];
if (val === '' || val === null || val === undefined) return '';
if (Array.isArray(val)) {
return val.reduce((results, val2) => {
if (val2) {
// Faster than string interpolation
results.push(encodeURIComponent(key) + '[]=' + encodeURIComponent(val2));
}
return results;
}, []).join('&');
}
return encodeURIComponent(key) + '=' + encodeURIComponent(val);
}).filter((x) => x.length).join('&');
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment