Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Callback returns undefined with chrome.storage.sync.get

I'm building a Chrome extension and I wrote this code.

var Options = function(){};

Options.prototype = {

    getMode: function(){
               return chrome.storage.sync.get("value", function(e){  
                 console.log(e); // it prints 'Object {value: "test"}'.       
                 return e;
               });
    },

    setMode: function(){
        chrome.storage.sync.set({"value": "test"}, function(e) {         
        })
    }
}

var options = new Options();
options.setMode();
console.log(options.getMode()); // it prints 'undefined'.

I expected it to print

Object {value: "set up"}

when I call options.getMode(), but it prints undefined.

Does anyone know how to fix this problem?

like image 683
crzyonez777 Avatar asked Sep 09 '13 13:09

crzyonez777


1 Answers

The chrome.storage API is asynchronous - it doesn't return it directly, rather passing it as an argument to the callback function. The function call itself always returns undefined.

This is often used to allow other methods to run without having to wait until something responds or completes - an example of this is setTimeout (only difference is that it returns a timer value, not undefined).

For example, take this:

setTimeout(function () { alert(1); }, 10000);
alert(0);

Because setTimeout is asynchronous, it will not stop all code until the entire function completes, rather returning initially, only calling a function when it is completed later on - this is why 0 comes up before 1.


For this reason, you cannot simply do something like:

// "foo" will always be undefined
var foo = asyncBar(function (e) { return e; }); 

Generally, you should put what you want to do in your callback (the function that is called when the asynchronous function is completed). This is a fairly common way of writing asynchronous code:

function getValue(callback) {
  chrome.storage.sync.get("value", callback);
}

You could place an entire portion of your code inside the callback - there's nothing stopping you from doing so. So instead of doing the following:

console.log(getValue()); // typical synchronous method of doing something

This would probably be a better idea:

// how it would be done in asynchronous code
getValue(function (value) {
  console.log(value);
}); 
like image 59
Qantas 94 Heavy Avatar answered Sep 30 '22 03:09

Qantas 94 Heavy