Get Query Params as Object

Nicholas Ortenzio wrote this little plugin:

jQuery.extend({

  getQueryParameters : function(str) {
	  return (str || document.location.search).replace(/(^\?)/,'').split("&").map(function(n){return n = n.split("="),this[n[0]] = n[1],this}.bind({}))[0];
  }

});

So if the URL is:

http://codepen.io/chriscoyier/pen/uszCr?lunch=sandwich&dinner=stirfry

You can do:

var queryParams = $.getQueryParameters();

And queryParams will be an object like:

{
   "lunch": "sandwich",
   "dinner": "stirfry"
}

Comments

  1. User Avatar
    Andrew Jones
    Permalink to comment#

    So very handy. Wondering if there’s a way to also provide downloadable snippets like this for easy importing into Codebox, etc.

  2. User Avatar
    zzzzBov
    Permalink to comment#

    I cringe every time I see custom query string parsing algorithms because they’re pretty much always wrong.

    For example, ?foo=bar;foo=baz should produce:

    {
        "foo": [
            "bar",
            "baz"
        ]
    }
    

    And that code obviously can’t.

    • User Avatar
      Ben Caplan
      Permalink to comment#

      zzzzBov, what about this as a modified alternative?

      jQuery.extend({
        getQueryParameters : function(str) {
          return (str || document.location.search).replace(/(^\?)/,'').split("&").map(function(n){
            return n = n.split("="),
            ( !this[n[0]] ? this[n[0]] = n[1] : ((typeof this[n[0]] === 'object') ? this[n[0]].push(n[1]) : this[n[0]]=[this[n[0]], n[1]]) ),
            this
          }.bind({}))[0];
        }
      });
      
    • User Avatar
      zzzzBov
      Permalink to comment#

      @Ben

      This is the sort of feature where you should set up unit tests before writing. With a little bit of testing, I found that the following strings failed:

      '?=&='
      '?foo=bar&foo=baz;foo=qux'
      ''*

      * I modified the algorithm to remove || document.location.search to test strings explicitly

    • User Avatar
      joe t
      Permalink to comment#

      @zzzzBav: If you pass that query string to PHP (assuming you’ve defined “;” as a param separator), it would produce the same as this script: last value wins the key. To produce the array you suggest, you’d need this: ?foo[]=bar;foo[]=baz. The script above would still only produce {"foo[]":"baz"}.

      It’s a narrow scope script not intended for advanced data structures. Taken in that context, it’s elegant, fast, and easy to implement.

    • User Avatar
      joe t
      Permalink to comment#

      Sorry, meant zzzzBov. :)

    • User Avatar
      zzzzBov
      Permalink to comment#

      @Joe t, PHP uses a completely different query string parsing standard. Use caution when parsing query strings that are used in PHP applications.

    • User Avatar
      joe t
      Permalink to comment#

      @zzzzBov, By that logic we should beware of query strings used by any language, as there is no broadly accepted standard. Ruby, PHP, Python, .Net… Who’s right? Which one should JavaScript follow? (And why is query part of the JavaScript location object yet there’s no built-in parser?)

      Granted, expecting a JavaScript query string parser to handle all variations out there is ludicrous. Due caution should always be exercised.

      It’s an example of how it can be done, not a universal solution. Since in most cases the programmer who uses it will also control the query string itself, it obviously should be adapted to need. :-)

  3. User Avatar
    Ben Caplan
    Permalink to comment#

    @zzzzBov I have to agree with @joe. I think the intended use case here would be “normal” query string use. What would be the use cases for the exceptions you found? I see the validity of your initial issue, in that checkboxes and multi-selects would render a query string with redundant keys, but special characters or equal signs without keys? I am interested to hear the situations you have encountered where these are useful cases.

    Also unit testing a proposed alternate script in a blog comment feed might be a bit excessive, no?

    • User Avatar
      zzzzBov
      Permalink to comment#

      The whole reason I brought it up is to make people aware that query string parsing is not something that should be left to a crummy home-brewed solution. Edge cases aren’t an issue until you’re bitten by them.

  4. User Avatar
    Rob
    Permalink to comment#

    This also doesn’t handle URL encoding. If a URL encoded query string is ran through this, the resulting object will still have the encoded text. Which in my experience is incorrect.

  5. User Avatar
    Ryan
    Permalink to comment#

    I think there should also be a minor update to the RegEx in the replace to:

    .replace(https://cdn.css-tricks.com/^.*(\?)/,'')
    

    This removes all text before the ? The original RegEx requires you to pass in

    ?param=val&param=val.
    

    The update allows you to pass in

    domain.com?param=val&param=val 
  6. User Avatar
    Niels Oeltjen
    Permalink to comment#

    jQuery now has $.getParams(url);

    • User Avatar
      http://www.justinas.tk

      Where do you found this information? Can you pass some link to documentation?

  7. User Avatar
    Eldon McGuinness
    Permalink to comment#

    Give this a try, seems to work with the test cases zzzBov mentioned. http://jsfiddle.net/EldonMcGuinness/cb57dusv/

  8. User Avatar
    Dhruv
    Permalink to comment#

    Should probably handle the no params case better. Modified version. Return {} incase of no/inconsistent str.

    $.extend({
              getQueryParameters : function(str) {
                  str = str || document.location.search;
                  return (!str && {}) || str.replace(/(^\?)/,'').split("&").map(function(n){return n = n.split("="),this[n[0]] = n[1],this}.bind({}))[0];
              }
            });
    
  9. User Avatar
    Alexandr Marchenko
    Permalink to comment#

    Query string parameters should be decoded. So here is fixed example:

    return (str || document.location.search).replace(/(^\?)/,'').split("&").map(function(n){return n = n.split("="),this[n[0]] = decodeURIComponent(n[1]),this}.bind({}))[0];
    

    What I have done is decorated n[1] with decodeURIComponent

  10. User Avatar
    Nathasha Loos
    Permalink to comment#

    I used this for my site today and made a small improvement to the method. Instead of using ‘map’ array function, I used ‘reduce’ function it returns a single object instead of an array.

    Code example:

    • User Avatar
      raja
      Permalink to comment#

      example_length=10&id=LAF-000021&id=LAF-000028 , I want to covet this json . but it
      id is only coming as array.

  11. User Avatar
    Sean
    Permalink to comment#

    Works great! However, JSHint doesn’t like this. It complains that there is an “Unexpected use of a comma operator.”

Submit a Comment

Posting Code

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.

icon-anchoricon-closeicon-emailicon-linkicon-logo-staricon-menuicon-nav-guideicon-searchicon-staricon-tag