queryStringToJSObject

by Ricky Curtice

HTML

<h1>
 Test Data
</h1>
<input type="text" id="input" value="?anarray=1.0&justanum=2&anarray=1.1&complexstr=%5Basf%5D&complexstr2=b%3Dar&openended&withextra=true" />
<pre id="outputTest"></pre>
<sub>* Note that the JSON display shows null when the value is actually undefined.  This is an artifact of using JSON.stringify().</sub>

<h1>
 Live QueryString Data
</h1>
<pre id="outputQS"></pre>

CSS

#input {
  width: 100%;
  display: block;
}

pre {
  min-height: 20em;
  background-color: #001100;
  color: #00aa00;
  padding: 1ex;
  border-radius: 1ex;
}

JavaScript

const queryStringToJSObject = searchString => {
  if (!searchString) return null;

  return searchString
    .replace(/^\?/, '') // Only trim off a single leading interrobang.
    .split('&')
    .reduce((result, next) => {
    	if (next === "") {
      	return result;
      }
      let pair = next.split('=');
      let key = decodeURIComponent(pair[0]);
      let value = typeof pair[1] !== "undefined" && decodeURIComponent(pair[1]) || undefined;
      if (result.hasOwnProperty(key)) { // Check to see if this property has been met before.
        if (Array.isArray(result[key])) { // Is it already an array?
          result[key].push(value);
        }
        else { // Make it an array.
          result[key] = [result[key], value];
        }
      }
      else { // First time seen, just add it.
        result[key] = value;
      }

      return result;
    }, {}
  );
};

// Simple read of query string
const searchData = queryStringToJSObject(window.location.search);

document.getElementById("outputQS").innerText = JSON.stringify(searchData, (k, v) => v === undefined ? null : v, '\t');

// Advanced usage for demo.
var testOutput = document.getElementById("outputTest"),
  testInput = document.getElementById("input");

function update() {
  testOutput.innerText = JSON.stringify(queryStringToJSObject(testInput.value), (k, v) => v === undefined ? null : v, '\t');
}
testInput.addEventListener("input", update);
update();