0
(function() {
"use strict";

var storage = chrome.storage.sync;
var localStorage = null;

function getOutsideScope(property) {
    if (localStorage.hasOwnProperty(property)) {
        return localStorage[property];
    }
}

function fulfill(data) {
    return data;
}

function rejected(err) {
    log(err);
}

window.app.storage = {
    get: function(storageKey, storageProp) {
        var promise = new Promise(function(fullfill, reject) {
            chrome.storage.sync.get(storageKey, function(data) {
                if (data.hasOwnProperty(storageKey)) {
                    fullfill(data[storageKey]);
                } else {
                    reject(new Error(storageKey + " does not exist in the storage values."));
                }
            });
        });
        return promise.then(fulfill, rejected);
    },
    set: function(storageKey, storageItem) {

    },
    onChanged: function(fn) {

    }
};

})();

So the above is my IIFE wrapper for chrome storage, and well the return is being a pain in the bleep. So I decided to give Promises a try, this is my first time so don't be too rough on me on this. Basically this is what I want to do

 var property = app.storage.get("properties");
 //property should equal "value"
 //except it returns undefined 

So adding the promises it does get the value except it returns this

Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: "value"}

Am I doing something wrong with Promises I've tried reading HTML5Rocks, the MDN, and video tutorials except it doesn't really mention much of how to return a value. This does NOT work

get:function(storageKey,storageProp) {
    chrome.storage.sync.get(storageKey,function(data) {
        //for simplicity and no error checking -_-
        return data[storageKey];
    });
}
EasyBB
  • 6,176
  • 9
  • 47
  • 77
  • 2
    Please format your code with proper indentation. It is not easy to read (and quite misleading) as is. – jfriend00 Sep 01 '15 at 04:04
  • Instead of `return promise.then(fulfill,rejected);`, you should just have `return promise;`. You already have code to call `fulfill()` and `reject()` in the function. Probably won't fix the problem, but definitely not what you want. – jfriend00 Sep 01 '15 at 04:05
  • 1
    The problem results from attempting to return data to synchronous code from asynchronous code. – Dan D. Sep 01 '15 at 04:05
  • Ok @jfriend00 it was difficult to do it on the markdown editor. I'll format it elsewhere and update. Also I'll try what you said – EasyBB Sep 01 '15 at 04:06
  • 1
    Yeah, the markdown editor basically sucks for dealing with code. You can't even do block indent. You are correct to format elsewhere, then bring it here. For a site so dedicated to programming (and relatively successful apparently), it is amazing to me how unfriendly the editor is for dealing with code. I've asked about the editor on meta and been laughed away by those who apparently don't understand. – jfriend00 Sep 01 '15 at 04:09
  • yes I understand that jFriend, I did the best i could and updated. FelixKings answer did not work so I'm trying yours now... @jfriend00 so it still returns that same object back to me -_-. – EasyBB Sep 01 '15 at 04:10
  • @EasyBB "FelixKings answer did not work so I'm trying yours now" --- the thing is that you now need to *understand* the promises and fix it yourself, not just wait for come copy-paste answer. – zerkms Sep 01 '15 at 04:13
  • My suggestion wasn't going to fix your problem, just unnecessary practice you were doing. – jfriend00 Sep 01 '15 at 04:14
  • I don't copy paste answers, I try to understand this, though I believe that the real issue is I'm thinking of this the wrong way and shouldn't be using a promise at all... – EasyBB Sep 01 '15 at 04:14
  • 1
    @EasyBB: Promises don't allow you to return values from an async function. Nothing can. You must learn to use callbacks. The only thing promises do is change the syntax from: `foo(callback)` to `foo().then(callback)` (there are other niceties like error handling but changing the syntax is the main thing promises do) – slebetman Sep 01 '15 at 05:04

1 Answers1

2

The function returns exactly what it is supposed to return: A promise. To get the value once the promise is fulfilled, you add a callback via .then:

app.storage.get("properties").then(function(property) {
    // property will be "value"
});

From MDN:

A Promise represents a proxy for a value not necessarily known when the promise is created. It allows you to associate handlers to an asynchronous action's eventual success value or failure reason. This lets asynchronous methods return values like synchronous methods: instead of the final value, the asynchronous method returns a promise of having a value at some point in the future.

[...]

A pending promise can become either fulfilled with a value, or rejected with a reason (error). When either of these happens, the associated handlers queued up by a promise's then method are called.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • This invocation of the code throws error. `doesn't match definition get(optional string or array or object keys, function callback)` – EasyBB Sep 01 '15 at 04:09
  • @EasyBB: I just copied your example and assume that your implement is correct. If any of these methods has to be called in a different then you should fix that. The invocation of `.then` is correct as you can verify by looking at the documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then – Felix Kling Sep 01 '15 at 04:11
  • Please reread the code, the example I should is how the overall code should work with out anything else. inside the `get` method is where I call `then` and once its fulfilled it should return what I need... no? – EasyBB Sep 01 '15 at 04:13
  • 1
    You seem to have a wrong expectation of promises. Promises do not magically make your code synchronous. You have to structure your code to work with promises. If your function returns a promise, then you have to work with that promise. – Felix Kling Sep 01 '15 at 04:15
  • @EasyBB once you're inside the promise - you cannot escape it and you can only handle the result inside its callback. So, no, you cannot return the plain data from your `get` method, it's simply impossible. – zerkms Sep 01 '15 at 04:15
  • Ok so I guess I was right that Promises are not what I want. – EasyBB Sep 01 '15 at 04:16
  • @EasyBB in this particular case it's likely what you want – zerkms Sep 01 '15 at 04:17
  • P.S. `fulfill` and `rejected` are defined inside the scope of the IIFE – EasyBB Sep 01 '15 at 04:17
  • 1
    @EasyBB: Well, promises make working with asynchronous code easier. If your code is asynchronous then your probably want to use them. – Felix Kling Sep 01 '15 at 04:17
  • 1
    @EasyBB: (missed that part) – Felix Kling Sep 01 '15 at 04:18
  • @zerkms not sure if `localStorage` which is what the chrome storage is built upon is async or sync. So that's my problem. I guess I have to figure that out. I need to get into Promises more though so I'm having a hard time grasping them. – EasyBB Sep 01 '15 at 04:18
  • @EasyBB "is built upon is async or sync" --- can you return a value without promises or callbacks from it? If not - it's likely to be not synchronous. https://developer.chrome.com/extensions/storage#method-StorageArea-get And "It's asynchronous" is stated explicitly on that page. – zerkms Sep 01 '15 at 04:19
  • @EasyBB: You probably want to have a look at http://stackoverflow.com/q/14220321/218196 . – Felix Kling Sep 01 '15 at 04:20
  • calling `chrome.storage.sync.get("property",fn` needs a function because it returns the data object if you change `property` to null it returns the entire storage property – EasyBB Sep 01 '15 at 04:20
  • not that simple lol. It still needs a function and if I try `return data` it is still undefined. I wish the docs told me if it were actually async or sync. – EasyBB Sep 01 '15 at 04:23
  • @EasyBB: The fact that you have to pass a callback function is a strong indicator that it is async. – Felix Kling Sep 01 '15 at 04:40
  • Ok... I'll figure something out then. Probably just can't assign and will have to assign inside the function. – EasyBB Sep 01 '15 at 05:01