I'm trying to utilize HTML5 sessionStorage to retain some data previously retrieved from an external API, so as to cache the data when it is later called again, rather than making a connection to retrieve redundant data that has already been retrieved this session.
function getItemWithTooltip(item_id, div_id) {
var xmlhttp2 = new XMLHttpRequest();
var url2 = "https://api.guildwars2.com/v2/items/"+item_id;
xmlhttp2.onreadystatechange=function() {if (xmlhttp2.readyState == 4 && xmlhttp2.status == 200) {parseItemTooltip(xmlhttp2.responseText);}};
xmlhttp2.open("GET", url2, true);
//xmlhttp2.send();
var item;
var cache_enabled = true;
// Cache results for quicker page loads
if (cache_enabled == true){
if (Storage !== void(0)) {
// Retrieve data (if stored)
if (sessionStorage[String(item_id)]) {
//item = JSON.parse(sessionStorage.getItem(String(item_id)));
item = JSON.parse(sessionStorage[item_id.toString()]);
//window.alert("sessionStorage: Retrieved");
//alert(typeof (item));
//alert(item);
}
}
}
if (item == null){
xmlhttp2.send();
}
function parseItemTooltip(response) {
//var item = JSON.parse(response);
if (item == null){
// Store data
if (cache_enabled == true){sessionStorage.setItem(item_id.toString(), JSON.stringify(response));}
//sessionStorage.setItem(String(item_id), item);
//if (cache_enabled == true){sessionStorage.setItem(String(item_id), response);}
//window.alert("sessionStorage: Stored");
item = JSON.parse(response);
}
//..More code here that was not relevant and removed to save space..
}
}
I think the issue has something to do with the fact that you
JSON.stringifythe response when storing it. The response is already a string, so that's going to "double-stringify" it and when you parse it you will only get the original string back.You do both
JSON.stringifyANDJSON.parseon the response text. This makes no sense for JSON, you should only need to do one of these. If you stringify a string, it will become "double-stringified". If you try to parse an object, you will get error becauseJSON.parserequires a string.Lets say your response text looks like this:
'{"property":"value"}'It's a string. Now, when you stringify it, it will become this:
'"{\"property\":\"value\"}"'When you parse this, like you do when getting it from
sessionStorage, you will only get the original string back. You would have to parse it again to get the object you want.When you do that parse on the response text directly, you correctly get the object:
So what you need to do is to store the response text in
sessionStoragewithout stringifying it.You're also only invoking
parseItemTooltipin the state change handler for the request, so it never gets invoked when you get the cached item. Looking at your full code, I can see that you do basically everything in this function so you need to invoke it explicitly when not performing the request.