I am trying to use the following code to set and get name value pairs in a Chrome Extension.
if (!this.Chrome_getValue || (this.Chrome_getValue.toString && this.Chrome_getValue.toString().indexOf("not supported") > -1)) {
this.Chrome_getValue = function (key, def) {
chrome.storage.local.get(key, function (result) {
return result[key];
});
};
this.Chrome_setValue = function (key, value) {
var obj = {};
obj[key] = value;
return chrome.storage.local.set(obj)
}
}
I am then invoking these as follows:
Chrome_setValue("City", "London");
var keyValue = Chrome_getValue("City");
The problem is the keyValue is always 'undefined' even if I put a 1 second delay in trying to read back the value. I understand this is because the 'chrome.storage.local.get' function is asynchronous.. the following code works fine.
Chrome_setValue("City", "London");
chrome.storage.local.get("City", function (result) {
alert(result["City"]);
});
Is there any way when binding the keyValue (using get
) I can force the code to wait for the function to return a response? Or perhaps I'm approaching this from the wrong angle. Essentially I am looking for a way I can abstract out the set
and get
methods for handling data within the chrome.storage framework? Ideally two simple functions I can call for setting and retrieving name value pairs.
Before I was using localStorage which was very straightforward.
//Set
localStorage["City"] = "London";
//Get
var keyValue = localStorage["City"];
QF_D, I'm into educated guesswork here, so be prepared for this not to work first time .....
..... here goes :
if (!this.Chrome_getValue || (this.Chrome_getValue.toString && this.Chrome_getValue.toString().indexOf("not supported") > -1)) {
this.Chrome_getValue = function (key, def) {
var dfrd = $.Deferred();
chrome.storage.local.get(key, function (result) {
dfrd.resolve(result[key]);
});
return dfrd.promise();
};
this.Chrome_setValue = function (key, value) {
var dfrd = $.Deferred();
var obj = {};
obj[key] = value;
var listen = function(changes, namespace) {
dfrd.resolve(changes[key]);
chrome.storage.onChanged.removeListener(listen);//remove, to prevent accumulation of listeners
}
chrome.storage.onChanged.addListener(listen);
chrome.storage.local.set(obj);
return dfrd.promise()
}
}
The get and set functions should thus return jQuery promises. The promise returned by the set function is resolved with a StorageChange
object defined here. In general you won't need this object, rather just respond to the promise being resolved.
Everything above is untested. I'm not too sure about :
chrome.storage.onChanged....
. Should it be chrome.storage.local.onChanged....
?.removeListener()
. It seems resonable that it should exist if addListener
exists, though I can't find any evidence of it.Well, it's essentially because the chrome.storage
API is asynchronous. You are facing something which is at the core of JavaScript.
What's executed in the chrome.storage.get
callback is not returned by chrome.storage.get
. You have 2 ways of dealing with it:
You really have to figure out the difference between synchronous and asynchronous.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With