Skip to content

Instantly share code, notes, and snippets.

@jdfm
Created November 15, 2013 16:02
Show Gist options
  • Save jdfm/7486731 to your computer and use it in GitHub Desktop.
Save jdfm/7486731 to your computer and use it in GitHub Desktop.
Takes data in a hierarchy and returns a string suitably formatted for a POST request's postBody or a GET request's query component.
/**
* querify
*
* Takes data in a hierarchy and returns a string suitably formatted for a POST
* request's postBody or a GET request's query component.
*
* Note:
* This function will not play well with circular referenced objects, it
* will result in an infinite loop. Most likely. I haven't tested
* that case.
*
* @param {Any} input The data you wish to querify
* @param {String} keyHierarchy A key hierarchy to use for subsequent key
* value pairs. If none is passed, it will
* be determined automatically based on the
* input passed. Ex:
* myKey[0], output: myKey[0][otherKey]
* @return {String} The formatted string. Ex:
* something=else&nothing=&arrays[0][a]=value&arrays[1]=0
*/
function querify(input, keyHierarchy){
var hasKeyHierarchy,
output,
key,
currentKey,
currentItem;
// This is a bit of a grey area... What to do if the user passes a falsey
// or a non object as input?
if(!input || typeof input !== 'object'){
if(typeof input === 'object' || typeof input === 'undefined'){
return '';
} else {
return encodeURIComponent(input);
}
}
// determine if there is a key hierarchy
hasKeyHierarchy = !!(keyHierarchy && typeof keyHierarchy === 'string');
output = [];
// we're using for .. in to generically iterate through the object (even if
// it is an array), the code becomes simpler this way
for(key in input){
// make sure we're not sending any prototype properties
if(!input.hasOwnProperty(key)){ continue; }
// let's prepare the current key
if(hasKeyHierarchy){
currentKey = keyHierarchy + '[' + encodeURIComponent(key) + ']';
} else {
currentKey = encodeURIComponent(key);
}
currentItem = input[key];
// in case of falsey, determine best course of action
if(!currentItem){
if(typeof currentItem === 'object' || typeof currentItem === 'undefined'){
output.push(currentKey + '=');
} else {
output.push(currentKey + '=' + encodeURIComponent(currentItem));
}
continue;
}
// recursively iterate through the object to extract all of the
// key-value pairs
if(typeof currentItem === 'object'){
output.push(querify(currentItem, currentKey));
continue;
}
// add a new key-value pair to the output
output.push(currentKey + '=' + encodeURIComponent(currentItem));
}
// if any property of the original input was an empty object add an empty
// entry for it in the output
if(hasKeyHierarchy && !output.length){
output.push(keyHierarchy + '=');
}
return output.join("&");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment