6

Consider this string: #page?param1=a&param2=b&param3=c

A hybrid application I have been working on uses window.location.hash to route the application to the right page. Often, these URLs contain parameters after the hash. Sure, this isn't standard, but it's a good solution that works nicely for our application.

I need to create a function that will take all of the parameters in the hash and return them in a object, for example: {param: value}.

I have tried other questions solution's that involve window.location.search but sadly that just returns an empty string when the parameters are after a hash.

My attempt looks like this:

return JSON.parse('{"' + decodeURI(window.location.hash).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}');

The solution is taken from another question that uses window.location.search but using window.location.hash doesn't quite work properly, the first parameter (after the question mark) shows as undefined.

How can I create a function that would return hash parameters in an object?

The desired result for the string above would be this:

{ param1: 'a', param2: 'b', param3: 'c' }
0

4 Answers 4

19

You can use this function:

function parseParms(str) {
    var pieces = str.split("&"), data = {}, i, parts;
    // process each query pair
    for (i = 0; i < pieces.length; i++) {
        parts = pieces[i].split("=");
        if (parts.length < 2) {
            parts.push("");
        }
        data[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
    }
    return data;
}

This is taken from the .parseParms() method of a larger set of functionality on github I wrote for parsing a URL into all its pieces.

Input is a string in the form of:

"aaa=1&bbb=99&name=Bob"

and it will return an object like this:

{aaa: 1, bbb: 99, name: "Bob"}

So, if you have other things in the string besides just the parameters above, then you would need to remove those first before calling this function.

Working demo:

function parseParms(str) {
    var pieces = str.split("&"), data = {}, i, parts;
    // process each query pair
    for (i = 0; i < pieces.length; i++) {
        parts = pieces[i].split("=");
        if (parts.length < 2) {
            parts.push("");
        }
        data[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
    }
    return data;
}

console.log(parseParms("aaa=1&bbb=99&name=Bob"));

Sign up to request clarification or add additional context in comments.

6 Comments

That's great thanks! Yes, I think the best way to do it would just be to split and remove everything before the '?'
This solution can't work with arrays in urls. Please see my example below.
@t1gor - So you downvoted the accepted answer that did exactly what the OP asked for, but doesn't meet some other requirement that was not in the question? Really? You're welcome to promote your own answer and try to convince the world it's a better answer, but you don't generally downvote good answers that meet the requirements stated in the question. Downvotes are generally reserved for wrong answers or answers that show bad practices.
@jfriend00 didn't really mean to offend you, sorry. Will restore the vote when I'll be allowed to.
@t1gor - I added a working demo so you should be able to restore it now.
|
2

the foreEach method on arrays makes it even shorter:

const result = {};
hash.split('&').forEach(item => {
    result[item.split('=')[0]] = decodeURIComponent(item.split('=')[1]);
});

Comments

0
function parseParms(str) 
{
  var pieces = str.split( "&" ), 
      data = {}, 
      i, parts, key;

  // Process each query pair
  for ( i = 0; i < pieces.length; i++ ) {
    parts = pieces[i].split( "=" );

    // No value, only key
    if ( parts.length < 2 ) {
      parts.push( "" );
    }

    key = decodeURIComponent( parts[ 0 ] );
    value = decodeURIComponent( parts[ 1 ] );

    // Key is an array
    if ( key.indexOf( "[]" ) !== -1 ) {
      key = key.substring( 0, key.indexOf( "[]" ) );

      // Check already there
      if ( "undefined" === typeof data[ key ] ) {
        data[ key ] = [];
      }

      data[ key ].push( value );
    } else {
      data[ key ] = value;
    }
  }
  return data;
}

Working example can be found here: https://jsbin.com/xitemecuvi/edit?js,console

Hope that helps.

Comments

0

function queryStringToObject (url){
const urlObj = new URL(url);
const queryString = urlObj.search.substring(1);
const queryStringArray = queryString.split('&')
let obj={};
queryStringArray.forEach(item=>{
  let itemArr = item.split('=')
  if(obj.hasOwnProperty(itemArr[0])){
    if(typeof obj[`${itemArr[0]}`] == 'string'){
      obj[`${itemArr[0]}`]=[obj[`${itemArr[0]}`]]
    }
    obj[`${itemArr[0]}`].push(itemArr[1])
  }
  else{
    obj[`${itemArr[0]}`]=itemArr[1]
  }

})

return obj;

}

console.log('--OUTPUT--',queryStringToObject('http://localhost:3000/api?brand=samsung&brand=apple&brand=lg&category=mobile'))

1 Comment

Please add some explanation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.