5

I want to get 2 values from chrome storage via chrome.storage.local.get() but if I try to return the values from the callback function, I get 'undefined'. If I console.log() them, they are actually logged. Why is that? I've read in some other posts, that I need to use a callback - but as far as my basic JS understanding goes, I already return the value from the callback frunction of get().

// this should load 2 keys from an object stored in chrome storage
function loadJiraUrlElements(){
    chrome.storage.local.get({companyName: '', jiraBaseUrl: ''}, function(items) {
        return (items.companyName + items.jiraBaseUrl);
     })
}

// I want to use this function to call the return value and populate a DOM element
function populateUrlFieldsWithUrlElements(){
    companyInput.value = loadJiraUrlElements()
}
Hannes
  • 53
  • 1
  • 3
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – wOxxOm Feb 13 '19 at 04:36

2 Answers2

7

You're getting undefined because you're returning to the callback function (ie the inner function), not the outer function, which you are trying to get the return value from.

You can use a promise with resolve so you can use a .then callback in your populateUrlFieldsWithUrlElements function to get the value you want:

function loadJiraUrlElements() {
  return new Promise(resolve => {
    chrome.storage.local.get({companyName: '', jiraBaseUrl: ''}, function(items) {
      resolve(items.companyName + items.jiraBaseUrl);
    })
  })
}

// I want to use this function to call the return value and populate a DOM element
function populateUrlFieldsWithUrlElements() {
  loadJiraUrlElements().then(result => {
    companyInput.value = result;
  })
}

Or you can use async/await in your second function if you don't wish to use the .then callback:

// I want to use this function to call the return value and populate a DOM element
async function populateUrlFieldsWithUrlElements() {
  companyInput.value = await loadJiraUrlElements();
}
Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
6

It's an async function, you can either wrap it under a Promise object or continue using the callback mechanism.

1.) Promise:

function loadJiraUrlElements() {
    return new Promise(function(resolve, reject) {
        chrome.storage.local.get({companyName: '', jiraBaseUrl: ''}, function(items) {
            resolve(items.companyName + items.jiraBaseUrl);
         })
    });
}

// And caller function changes to 
function populateUrlFieldsWithUrlElements(){
    loadJiraUrlElements().then(function(value) {
        companyInput.value = value;
    })
}

2.) Callback:

function loadJiraUrlElements(cb){
    chrome.storage.local.get({companyName: '', jiraBaseUrl: ''}, function(items) {
        cb && cb(items.companyName + items.jiraBaseUrl);
     })
}

function populateUrlFieldsWithUrlElements(){
    loadJiraUrlElements(function(value) {
        companyInput.value = value;
    })

}
varun agarwal
  • 1,491
  • 6
  • 9