user948438237
user948438237

Reputation: 273

Split and parse window.location.hash

I'm facing issues with splitting and parsing window.location.hash correctly.

First of all, we get few parameters in hash, ex:

#loc=austria&mr=1&min=10&max=89

As you surely see it's been created for search. When user clicks on pagination link page is being reloaded with the hash. So far so good.

I created function initialise() that is calling every time when there's hash in the URL:

if (window.location.hash) {
    var params = (window.location.hash.substr(1)).split("&");

    for (i = 0; i < params.length; i++)
    {
        var a = params[i].split("=");
        // Now every parameter from the hash is beind handled this way
        if (a[0] == "loc")
        {
            locationList(a[1]);
        }
    }
}

       

Everythig is almost working... When I choose all search params hash is being... cut. For unknown reason for me. I tried to use if( params.indexOf('loc') ) instead of a[0] == "loc" without any luck.

Could you lend me a hand?

Edit
Of course, I was using var a = ... in the loop, it was only copy-paste error.

Upvotes: 26

Views: 46119

Answers (4)

KooiInc
KooiInc

Reputation: 122966

You don't need a loop, if it's only the value of loc from the hash you're after. This should also work.

var lochash    = location.hash.substr(1),
    mylocation = lochash.substr(lochash.search(/(?<=^|&)loc=/))
                  .split('&')[0]
                  .split('=')[1];
if (mylocation) {
   locationList(myLocation);
}

Concerning the trunctating of the hash after a page reload: imho that isn't related to your loop.

Edit A more modern and more accurate approach:

const result = document.querySelector("#result");
const hash2Obj = "loc=austria&mr=1&test123=test=123&min=10&max=89"
      .split("&")
      .map(v => v.split(`=`, 1).concat(v.split(`=`).slice(1).join(`=`)) )
      .reduce( (pre, [key, value]) => ({ ...pre, [key]: value }), {} );
          
result.textContent += `loc => ${hash2Obj.loc}
----
*hash2Obj (stringified):
${JSON.stringify(hash2Obj, null, ' ')}`;
<pre id="result"></pre>

Upvotes: 44

yorg
yorg

Reputation: 664

When parsing the hash, you may have to handle unescaped = characters. In this case, the use of split is not recommended. In addition, you could also handle empty hash, empty values (ususally interpreted as true) and use decodeURIComponent for encoded values.

const hash2Obj = function (hash) {
  // remove first char if necessary
  hash = (hash && (hash.charAt(0) === '#' || hash.charAt(0) === '?') ? hash.slice(1) : hash);
  // return empty object if empty
  if (!hash) return {};
  const obj = {};
  hash
  .split("&")
  .forEach(v => {
    // seek only first '=' char
    const id = v.indexOf('=');
    const [key, value] = id > -1 ? [v.slice(0, id), decodeURIComponent(v.slice(id + 1))]
    // handle absence of value as true
    : [v, true];
    if (key in obj) {
      // repeating values are usually intepreted as array
      if (!(obj[key] instanceof Array)) obj[key] = [obj[key]];
      obj[key].push(value);
    } else {
      obj[key] = value;
    }
  });
  return obj;
};

const getSearch = function () {
  return hash2Obj(window.location.search);
};
const getHash = function () {
  return hash2Obj(window.location.hash);
};

Upvotes: 0

Yashwanth M
Yashwanth M

Reputation: 263

This should be a rather simpler way to read from location.hash:

    var hash = window.location.hash.substring(1);
    var params = {}
    hash.split('&').map(hk => { 
      let temp = hk.split('='); 
        params[temp[0]] = temp[1] 
    });
    console.log(params); //Here are the params to use

and then, you could use

params.access_token //access_token 
params.id //id 

and other params that are available inside the hash

Upvotes: 20

detaylor
detaylor

Reputation: 7280

params.indexOf('loc') will not return a value as loc does not exist within the params array. The item that you are looking for in the example provided is loc=austria. If you are only selecting by the key then you would need some looping to examine each key-value pair.

Upvotes: 0

Related Questions