Skip to content

Instantly share code, notes, and snippets.

@pirate
Last active December 15, 2023 07:17
Show Gist options
  • Star 54 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save pirate/9298155edda679510723 to your computer and use it in GitHub Desktop.
Save pirate/9298155edda679510723 to your computer and use it in GitHub Desktop.
Parse URL query parameters in ES6
function getUrlParams(search) {
const hashes = search.slice(search.indexOf('?') + 1).split('&')
const params = {}
hashes.map(hash => {
const [key, val] = hash.split('=')
params[key] = decodeURIComponent(val)
})
return params
}
console.log(getUrlParams(window.location.search))
@pirate
Copy link
Author

pirate commented Jan 9, 2020

That's not a valid value @zerocoolElite, it needs to be URL-encoded (= becomes %3D when URL-encoded).

@arondiploma
Copy link

That's not a valid value @zerocoolElite, it needs to be URL-encoded (= becomes %3D when URL-encoded).

Then the search string should be encoded first before passing to getUrlParams()?

@legend80s
Copy link

legend80s commented Mar 8, 2020

I've tested all the functions above by https://runkit.com/embed/n18yhf9u2nqc and the conclusion is that url-parse and URLSearchParams is the rightest and most expected ones against the standard url - Node.js built-in module. Even the query-string module is not work as expected.

const search = '?abc=foo&def=[asf]&xyz==5&flag&&double&q=test1=test2&keyB=hff92hfgg=';

console.log((search));

const url = require('url')
console.log('0. url - the Node.js built-in module √');
console.log(url.parse(search, true).query);

console.log('1. queryString ×');
console.log(queryString.parse(search));

const parse = require('url-parse')
console.log('2. url-parse √');
console.log(parse(search, true).query);

console.log('3. URLSearchParams √');
console.log([...new URLSearchParams(search).entries()].reduce((q, [k, v]) => Object.assign(q, {[k]: v}), {}))

result:

?abc=foo&def=[asf]&xyz==5&flag&&double&q=test1=test2&keyB=hff92hfgg=

0. url - the Node.js built-in module √
Object {abc: "foo", def: "[asf]", double: "", flag: "", keyB: "hff92hfgg=", q: "test1=test2", xyz: "=5"}

1. queryString ×
Object {: null, abc: "foo", def: "[asf]", double: null, flag: null, keyB: "hff92hfgg=", q: "test1=test2", xyz: "=5"}

2. url-parse √
Object {abc: "foo", def: "[asf]", double: "", flag: "", keyB: "hff92hfgg=", q: "test1=test2", xyz: "=5"}

3. URLSearchParams √
Object {abc: "foo", def: "[asf]", double: "", flag: "", keyB: "hff92hfgg=", q: "test1=test2", xyz: "=5"}

@raveren
Copy link

raveren commented Apr 21, 2020

So this fails if you have select multiple - or any other input with multiple values that's named with square brackets:

<select name="statuses[]" multiple>...

Here's a slight adjustment, hopefully I'm not stepping on any edge cases:

function getUrlParams(search) {
    const hashes = search.slice(search.indexOf('?') + 1).split('&')
    const params = {}
    hashes.map(hash => {
        let [key, val] = hash.split('=')
        key = decodeURIComponent(key)
        if (key.indexOf('[') > -1) { // handle multiple type inputs
            if (typeof params[key] === 'undefined') {
                params[key] = []
            }

            params[key].push(decodeURIComponent(val))
        } else {
            params[key] = decodeURIComponent(val)
        }
    })
    return params
}

@eyecatchup
Copy link

eyecatchup commented Apr 24, 2020

Unfortunately even the native URLSearchParams implementation doesn't handle array query parameters. :(

So, here's another take on array query parameters. Tested on

https://gist.github.com/pirate/9298155edda679510723?abc=foo&def=[asf]&xyz==5&flag&&double&q=test1=test2&keyB=hff92hfgg=&arr[]=ArrayValue1&arr[]=ArrayValue2&arr[]=ArrayValue3&arr2[0]=ArrayValue1&arr2[1]=ArrayValue2&arr2[2]=ArrayValue3&fields=kind,items(title,characteristics/length)
const getQueryParams = () => {
    let params = {};
    (new URLSearchParams(document.location.search)).forEach((d, e) => {
      let a = decodeURIComponent(e), c = decodeURIComponent(d)
      if (a.endsWith("[]")) {
        a = a.replace("[]", ""), params[a] || (params[a] = []), params[a].push(c)
      } else {
        let b = a.match(/\[([a-z0-9_\/\s,.-])+\]$/g)
        b ? (a = a.replace(b, ""), b = b[0].replace("[", "").replace("]", ""), params[a] || (params[a] = []), params[a][b] = c) : params[a] = c
      }
    })
    return params
}

@marcodpt
Copy link

marcodpt commented May 9, 2021

I create an alternative project if you want to use es6 module, with a very simple api:
query

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