Skip to content

Instantly share code, notes, and snippets.

@formix
Last active November 9, 2018 15:34
Show Gist options
  • Save formix/d1219446ed99a78c8685d668c98a4576 to your computer and use it in GitHub Desktop.
Save formix/d1219446ed99a78c8685d668c98a4576 to your computer and use it in GitHub Desktop.
Convert an URL query string parameter list to a Javascript object.
//***************************************************************************
// Copyright 2018 Jean-Philippe Gravel, P.Eng., PSEM
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//***************************************************************************
// Version: 1.0.0
// Release date: 2018-11-09
// https://xkcd.com/1179/
let paramRegex = /[?&](?:([^?&=]+)=([^?&=]+))|[?&]([^?&=]+)/g;
let objectRegex = /([^?&=\[\]]+)\[([^?&=]+)\]/;
let arrayRegex = /^([^?&=\[\]]+)\[\]$/;
let numberRegex = /^[+-]?\d+(\.\d+)?$/;
let boolRegex = /true|false/i;
// Creates an object from the URL's query string parameters.
function queryString(url) {
let o = {};
let m = null;
while (m = paramRegex.exec(url)) {
let key = (m[1] || m[3]);
let value = _parse(m[2] || true);
_assign(o, key, value);
}
return o;
}
function _parse(value) {
if (typeof value === "string") {
if (numberRegex.test(value)) {
return Number(value);
} else if (boolRegex.test(value)) {
return value.toLowerCase() === "true";
}
}
return value;
}
function _assign(o, key, value) {
let arrMatch = arrayRegex.exec(key);
if (arrMatch) {
key = arrMatch[1];
if (!o.hasOwnProperty(key)) {
o[key] = [];
}
}
let objMatch = objectRegex.exec(key);
if (objMatch) {
if (!o.hasOwnProperty(objMatch[1])) {
o[objMatch[1]] = {};
}
_assign(o[objMatch[1]], objMatch[2], value);
} else {
if (o.hasOwnProperty(key)) {
if(o[key] instanceof Array) {
o[key].push(value);
} else {
o[key] = [o[key], value];
}
} else {
o[key] = value;
}
}
}
@formix
Copy link
Author

formix commented Nov 8, 2018

The following URL string:

"http://ddd.com?start&a=hello&b=world&middle&c=1.7276&c=2&c=3&exists=false&end"

becomes

{
  "start": true,
  "a": "hello",
  "b": "world",
  "middle": true,
  "c": [
    1.7276,
    2,
    3
  ],
  "exists": false,
  "end": true
}

@formix
Copy link
Author

formix commented Nov 9, 2018

The following URL string:

"http://ddd.com?start&a=hello&b=world&middle&c=1.7276&c=2&c=3&end&exists=false&this[that]=yes&this[this]=no&this[is[deep]]=deeper"

becomes:

{
  "start": true,
  "a": "hello",
  "b": "world",
  "middle": true,
  "c": [
    1.7276,
    2,
    3
  ],
  "end": true,
  "exists": false,
  "this": {
    "that": "yes",
    "this": "no",
    "is": {
      "deep": "deeper"
    }
  }
}

@formix
Copy link
Author

formix commented Nov 9, 2018

The following URL string:

"http://ddd.com?arr[]=test&arr[]=cdf"

becomes:

{
  "arr": [
    "test",
    "cdf"
  ]
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment