1

From my understanding, a promise's then method will only execute once a promise has been fulfilled.

However, in displayAdParams below, the second then block is executing even when getTabParamsFromStorage has not returned a promise/not fulfilled. This causes 'params' in the second then block to be undefined.

function displayAdParams() {
    getTabId().then(tabId => {
        return getTabParamsFromStorage(tabId);
    }).then(params => {
        console.log('b', params);
        updatePopupWithStandardParams(params.shift());
    });
}

function getTabId() {
    return new Promise((resolve, reject) => {
        let queryInfo = {active: true, currentWindow: true};
        chrome.tabs.query(queryInfo, tabs => {
            resolve(String(tabs[0].id));
        });
    });
}

This version of getTabParamsFromStorage doesn't work (Using Promise.resolve)

// This doesn't work
function getTabParamsFromStorage(tabId) {
    chrome.storage.local.get(tabId, items => {
        console.log('a', items[tabId]);
        return Promise.resolve(items[tabId]);
    });
}

/* output
popup.js:7 b undefined
TypeError: Cannot read property 'shift' of undefined
    at getTabId.then.catch.then.params (popup.js:8)
popup.js:47 a Array(7)
*/

This version of getTabParamsFromStorage works fine (Using new Promise)

// This works
function getTabParamsFromStorage(tabId) {
    return new Promise((resolve, reject) => {
        chrome.storage.local.get(tabId, items => {
            console.log('a', items[tabId]);
            resolve(items[tabId]);
        });
    });
}

Why is this happening and what can I do to get the first version of getTabParamsFromStorage working?

jay
  • 53
  • 5
  • 3
    You can't use `return Promise.resolve` asynchronously like that since the outer block has already `return`ed `undefined` ; `return new Promise` is the only way to do it. – CertainPerformance May 15 '18 at 04:44
  • You need to add async await inside your displayAdParams method. – Harish Soni May 15 '18 at 04:44
  • 1
    @HarishSoni That would change nothing. – CertainPerformance May 15 '18 at 04:45
  • Thats how it is done. The async await will cause the GetTabParamsFrom storage to execute completely and then it will go to the next then – Harish Soni May 15 '18 at 04:47
  • 2
    @HarishSoni Not if `getTabParamsFromStorage` doesn't return a `Promise` (which it currently isn't in the first snippet), and if it did return a `Promise`, then OP's `.then`s would work just fine. `async`/`await` wouldn't resolve anything – CertainPerformance May 15 '18 at 04:49
  • He he is not adding then on getparamsfromsstorage. So how the then mehtod will be used.? – Harish Soni May 15 '18 at 04:52
  • this `items => { console.log('a', items[tabId]); return Promise.resolve(items[tabId]); }` is the function that returns a promise. the surrounding function has no `return` statement whatsoever. That's why that version can not work. Plus, I don't know wether `chrome.storage.local.get()` is even using/propagating the returned value from the passed callback function (your promise) or wether it's completely ignoring it. – Thomas May 15 '18 at 04:58
  • @Thomas I have tested, and `chrome.storage.local.get()` is definitely receiving the value from my previous Promise. I assume that means a promise becomes fulfilled even when I don't explicitly resolve it? (Which I guess is why my 2nd then block executes) – jay May 15 '18 at 05:16
  • @jay, There are multiple ways to resolve a promise. `Promise.resolve(value)` is one way where you get an already resolved promise. `previousPromise.then(fn)` returns a promise that resolves to the value that is returned by `fn` as soon as `fn` is executed; *or if you return a promise, then it resolves to the result of that promise*. `new Promise(resolve => ...)` **is not** the only way to get a resolved promise. But that doesn't mean that promises resolve somehow automatically. – Thomas May 15 '18 at 05:39
  • That's really obvious basic js stuff and the first comment already explained everything in a sufficiently verbose manner to be promoted to an answer. – wOxxOm May 15 '18 at 08:51

1 Answers1

-1

You need to execute it like this in order to get the correct params. Try this one and let me know if this works or not

function displayAdParams() {
    getTabId().then( async tabId => 
       cosnt params = await  
getTabParamsFromStorage(tabId);
        console.log('b', params);
        updatePopupWithStandardParams(params.shift());
    });
}
Harish Soni
  • 1,796
  • 12
  • 27
  • It won't work, as you have mismatching brackets. And his code is better than these nested promise chains. Nesting promise chains like that is something you're trying to avoid, not encourage. – Thomas May 15 '18 at 05:02
  • Yup made an edit now using async await he can easily get the params – Harish Soni May 15 '18 at 05:04
  • FYI, just tested (before your edit) and also doesn't work (even with the correct brackets). getTabParamsFromStorage will still return undefined. – jay May 15 '18 at 05:06