How do I run a function once session storage is != undefined - javascript

I am in a situation wherein I have a an external JavaScript file that makes an ajax call and saves certain data to session storage. The JavaScript file loads from an external site and therefore, I cannot edit it.
I need to run a function to consume the saved data as soon as it loads into session storage. How can I trigger a function once this data loads?

Maybe this can help you:
window.onstorage = function(e) {
console.log('The ' + e.key + ' key has been changed from ' + e.oldValue + ' to ' + e.newValue + '.');
};
More info here and here
So you could subscribe to your session key changes with (not tested):
window.onstorage = function(e) {
if (
e.storageArea === sessionStorage &&
e.key === "<your_key>" &&
e.oldValue === undefined &&
e.newValue !== undefined
) {
console.log("my key is not undefined anymore")
}
};
UPDATE: So it seems that it is not working for you. Then you can try something like this (using interval to check if sessionStorage changes):
var INTERVAL = 2000;
// Then, in your code you can check every `INTERVAL` milleconds
// if the sessionKey you need is not null
console.log("Program starts");
// You can limit your intents too
var limit = 5;
var intervalId = setInterval(function() {
console.log("Checking sessionStorage");
var test = sessionStorage.getItem("test");
if (test !== null) {
console.log("'test' is now defined: " + test);
clearInterval(intervalId);
}
if (--limit <= 0) {
console.log("'test' has not changed");
clearInterval(intervalId);
}
}, INTERVAL);
Test here: https://jsbin.com/tukubutoje/edit?js,console

See StorageEvent:
A StorageEvent is sent to a window when a storage area it has access to is changed within the context of another document.
For example:
window.addEventListener('storage', function(e) {
document.querySelector('.my-key').textContent = e.key;
document.querySelector('.my-old').textContent = e.oldValue;
document.querySelector('.my-new').textContent = e.newValue;
document.querySelector('.my-url').textContent = e.url;
document.querySelector('.my-storage').textContent = e.storageArea;
});
Here we add an event listener to the window object that fires when the Storage object associated with the current origin is changed. As you can see above, the event object associated with this event has a number of properties containing useful information — the key of the data that changed, the old value before the change, the new value after that change, the URL of the document that changed the storage, and the storage object itself.

Related

How to show different localstorage for two folders in a domain

I have a folder called https://example.com/foldera and https://example.com/folderb. I want different local storage for these two. I am using simplecart.js. In this the code referring to local storage is
localStorage = window.localStorage,
// storage
save: function () {
simpleCart.trigger('beforeSave');
var items = {};
// save all the items
simpleCart.each(function (item) {
items[item.id()] = simpleCart.extend(item.fields(), item.options());
});
localStorage.setItem(namespace + "_items", JSON.stringify(items));
simpleCart.trigger('afterSave');
},
load: function () {
// empty without the update
sc_items = {};
var items = localStorage.getItem(namespace + "_items");
if (!items) {
return;
}
/************ HTML5 Local Storage Support *************/
(function () {if (!this.localStorage)if (this.globalStorage)try {this.localStorage=this.globalStorage}catch(e) {}else{var a=document.createElement("div");a.style.display="none";document.getElementsByTagName("head")[0].appendChild(a);if (a.addBehavior) {a.addBehavior("#default#userdata");var d=this.localStorage={length:0,setItem:function (b,d) {a.load("localStorage");b=c(b);a.getAttribute(b)||this.length++;a.setAttribute(b,d);a.save("localStorage")},getItem:function (b) {a.load("localStorage");b=c(b);return a.getAttribute(b)},
removeItem:function (b) {a.load("localStorage");b=c(b);a.removeAttribute(b);a.save("localStorage");this.length=0},clear:function () {a.load("localStorage");for (var b=0;attr=a.XMLDocument.documentElement.attributes[b++];)a.removeAttribute(attr.name);a.save("localStorage");this.length=0},key:function (b) {a.load("localStorage");return a.XMLDocument.documentElement.attributes[b]}},c=function (a) {return a.replace(/[^-._0-9A-Za-z\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u37f-\u1fff\u200c-\u200d\u203f\u2040\u2070-\u218f]/g,
"-")};a.load("localStorage");d.length=a.XMLDocument.documentElement.attributes.length}}})();
I changed some lines like ,
var url = new URL(window.location.href);
var prefix = url.replace("https://example.com/", "");
simpleCart.each(function (item) {
items[prefix+item.id()] = simpleCart.extend(item.fields(), item.options());
});
...
...
It add prefix for localstorage, but it dosn't prevent from sharing space in localstorage as in foldera it gets foldera prefix and folderb it gets folderb prefix. But the item still present in both folders, only prefix changes.
You can't. There is one local storage per domain.
First answer is you can't as described by others that There is one local storage per domain but there is an alternative solution...
A year ago i was also facing same problem so i create this function you can use this.
but as i am a new developer to JS and can't understand your code so this code may be diffrent from your requirment.
function my_local_storage(name,value,folder){
if(folder=='' || folder==null){
folder = window.location.pathname.slice(1);
}
if(typeof value!=='undefined' && value!==null && typeof(Storage)){
if(value===''){
localStorage.removeItem(folder.name);return true;
}
if(typeof value=='object'){
value=JSON.stringify(value);
}
localStorage.setItem(folder.name,value);
return true;
}
else if (typeof(Storage) && localStorage.getItem(folder.name) !== null)
{
return localStorage.getItem(folder.name);
}
return null;
}
To save new storage for key name and value John just call this function my_local_storage("name","John")
To get value of name key my_local_storage("name")
To remove value of name key my_local_storage("name","")
To Access other folders storage value use my_local_storage("name",null,"folder2")

Parse Javascript API Cloud Code afterSave with access to beforeSave values

I'm using Parse Cloud Code to do before/afterSave processing. I'd check the beforeSave value of an attribute in the afterSave hook - for example, do something when parseObj.get('status') transitions from processing => complete. I can get access to the oldVal/newVal for changed attributes in the beforeSave handler, but I can't find a way to pass the oldVal to the afterSave handler without saving as a DB field.
I tried to pass the values as an attribute to the response and response.object objects, neither makes it through to the afterSave
Parse.Cloud.beforeSave('ParseObj', function(request, response) {
var checkDirty, isDirty, parseObj, prevQ;
// request keys=["object","installationId","user","master"]
if (request.object.isNew()) {
return response.success();
} else {
parseObj = request.object;
checkDirty = ['status']; // array of all attrs to check
isDirty = [];
_.each(checkDirty, function(attr) {
if (parseObj.dirty(attr)) {
isDirty.push(attr);
}
});
console.log("isDirty=" + JSON.stringify(isDirty));
if (isDirty.length) {
prevQ = new Parse.Query('ParseObj');
return prevQ.get(parseObj.id).then(function(prevParseObj) {
var newVal, oldVal;
console.log("prevParseObj, id=" + prevParseObj.id);
oldVal = _.pick(prevParseObj.toJSON(), isDirty);
_beforeSave(parseObj, oldVal); // do something here
request.previousValues = oldVal
request.object.previousValues = oldVal
return response.success();
}, function(err) {
return response.error("parsObj NOT FOUND, parseObj.id=" + parseObj.id);
});
} else {
return response.success();
}
}
});
Parse.Cloud.afterSave('ParseObj', function(request) {
var parseObj;
// request keys=["object","installationId","user","master"],
oldVal = request.previousValues // undefined
oldVal = request.object.previousValues // also, undefined
parseObj = request.object;
_afterSave(parseObj, oldVal) // do something else here
return;
});
Any ideas?
I looked into this some more, and I ended up saving to the Parse object temporarily and removing it like this:
//Add the value you need to the object prior to saving using an "oldValue" key
yourPFObject["oldValue"] = value (this is in your SDK somewhere where the save happens)
//Get that value in afterSave in Cloud Code
var old = object.get("oldValue")
//Do whatever you need to do with "old"...
//Remove the temporary old value so it doesn't stay in the database
object.unset("oldValue")
object.save()
I hope that helps. Good luck!

dojo.cookie(id) not able to look up cookie by id intermittently

_setPrintExportCookieInterval: function(/**String*/requestId, /**function*/closePopup) {
//have the interval autoexpire after some amount of seconds
var count = 0;
var intervalMs = 2000;
var intervalId = self.setInterval(function() {
var reportCookie = dojo.cookie(requestId);
console.debug('requestId ' + requestId);
if(reportCookie || count > 300000) { //5 mins
//if there's a status failure, don't close the window
console.debug('reportCookie ' + reportCookie);
if(reportCookie == undefined){
console.debug("print/export request returned with undefined status ");
} else if(reportCookie == "success") {
closePopup();
} else{
console.debug("print/export request returned with nonstandard status " + reportCookie);
}
window.clearInterval(intervalId);
//delete the cookie
dojo.cookie(requestId, null, {path: "/", expires: -1});
//destroy the iframe
//dojo.destroy(dojo.byId(requestId));
};
count+=intervalMs;
}, intervalMs);
return intervalId;
},
I'm having problems with the above javascript function. The problem generally is that sometimes:
var reportCookie = dojo.cookie(requestId);
returns null, but when I look in my browser's debugging tool I'm able to see that the cookie exists with a value of success. This happens one in every 10 times this function is called. Any ideas why dojo.cookie() is not able to look up the cookie by ID only some of the time?
Make sure that you specify the path when you are retrieving the cookie, otherwise it defaults to the current location. This will allow you to get the Cookie from any path within your domain.
dojo.cookie(requestId, null, {path: "/" });

How to run a setInterval that loops and tries a max of 10 times before breaking?

I have the following to try to reload on a connection drop:
setInterval(window.location.reload(), 1000);
My concern with this is that it could continue forever, ddos'ing my application.
How can I update the above to try at max 20 times before giving up and breaking?
Thank you
This makes me feel dirty, but you could update/extract the window hash with each refresh:
function hack () {
var last = parseInt(location.hash.slice(1));
if (last < 20) {
window.location.hash = last + 1;
window.location.reload();
}
}
window.location.hash = 0;
setTimeout(hack, 1000);
You need to persist some counter state from one page load to the next so you can know when 20 reloads have been done. Your options are:
A hash value
A query parameter
A cookie value
Something stored in local storage
If you don't need this value to persist beyond just the reloads of this page, then options 1) and 2) are better as they are only as persistent as you need. A hash value will not be sent to your server, but could interfere with other uses of the hash value. A query parameter would be sent to the server, but any reasonable server will ignore query values it doesn't know and it won't interfere with anything else. I'd probably pick a query parameter and have actually used one to avoid infinite redirection loops in some of my code. You could implement option 2) like this:
function checkAutoReload() {
var currentCnt = 0;
var re = /(\?|&)(reloadCnt=)(\d+)/;
var param = window.location.search.match(re), newURL;
if (param) {
currentCnt = parseInt(param[3], 10);
newURL = window.location.href.replace(re, "$1$2" + (currentCnt + 1))
} else {
newURL = window.location.href;
newURL += window.location.search ? "&" : "?";
newURL += "reloadCnt=1";
}
if (currentCnt < 20) {
window.location.replace(newURL);
}
}
setTimeout(checkAutoReload, 1000);
Notice, there's no need for a setInterval() because a given page's code only runs once before it either reloads or finds that it is done reloading.
Store the reloadCount in localStorage
MDN DOM Storage
var maxReload = 20;
var reloadPage = function() {
if (typeof a !== "undefined" && a !== null) {
console.log(localStorage.reloadCount);
localStorage.reloadCount = 0;
};
var reloadCount = parseInt(localStorage.reloadCount, 10);
console.log(reloadCount);
if (reloadCount < maxReload) {
reloadCount += 1;
localStorage.reloadCount = reloadCount;
// RELOAD CODE HERE
};
};
// call reloadPage from your code
reloadPage();

Javascript Variable Scope Confusion

In the following code snippet I've declared the variable "id" within the submit function. I attempt to assign a value to it within a nested function but it doesn't appear to be within scope and I don't know why.
$(document).ready(function() {
if (typeof(localStorage) == 'undefined' ) {
alert('Your browser does not support HTML5 localStorage. Try upgrading.');
}
else {
$("#logForm").submit(function(){
var id;
chrome.bookmarks.getRecent(1, function(mostrecent) {
getLastId(mostrecent);
});
function getLastId(mostrecent) {
mostrecent.forEach(function(mostrecent) {
lastId = mostrecent.id;
alert(lastId + ' was last id');
id = lastId;
})
}
alert(id + ' outside function');
Bonus Question - If you know a better way to pull the last-used id from chrome for a bookmark would love to know what it is. I had to pull recent which doesn't account for the possibility of an added and then deleted last bookmark which would have incremented the index.
This should do it:
$("#logForm").submit(function() {
var id;
chrome.bookmarks.getRecent(1, function(arr) {
id = arr.pop().id;
});
// do stuff with id
});

Categories

Resources