How do I wait for a javascript function to return a response using Chrome.storage API?
google-chrome, google-chrome-extension, javascript, jquery
Solution
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.
Problem
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"]; ```