Reputation: 273
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
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
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
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
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