How to wait for asynchronous chrome.storage.local.get() to finish before continuing execution
Asked Answered
B

4

13

I have two calls to chrome.storage.local.get(). I need for these calls to finish before continuing executing the rest of the code (calling continueCode() function) for my chrome extension, but I'm not sure how to do this, here is my code.

function getData() {
    chrome.storage.local.get(['key'], function(result) {
        if (Object.values(result)[0] != undefined) {
            object1.innerHTML = Object.values(result)[0].val;
        }
    });

    chrome.storage.local.get(['key2'], function(result) {
         if (Object.values(result)[0] != undefined) {
             object2.innerHTML = Object.values(result)[0].val;
         }
    });

    continueCode();
}
Brockie answered 21/12, 2019 at 21:38 Comment(0)
B
-2

You need to wait for both callback function that you pass to chrome.storage.local.get(..) to be executed before you call continueCode(), also, you can check both storage properties with a single call, here is an example:

function getData() {
  chrome.storage.local.get(['key', 'key2'], function(result) {
    if (typeof result.key !== 'undefined') {
      object1.innerHTML = result.key.val;
    } 
    if (typeof result.key2 !== 'undefined') {
      object2.innerHTML = result.key2.val;
    } 
    continueCode();
  }
}
Bono answered 22/12, 2019 at 2:2 Comment(7)
I was having some trouble with storing and getting objects of two different keys, but I'll try this out.Brockie
so continueCode() will execute immediately after the if conditionals are checked (and if they are true) and the innerHTML of the object is set, because in my continueCode() I get object1 or object2 from the HTML by calling document.getElementById()Brockie
@NoahTanenholtz No, continueCode() will be executed no matter if the properties are set or not.Bono
The issue that I'm having is that object1 is a table and I need to remove, add, and sort rows from the table. I need to be able to do this after the object1.innerHTML is set and updated, the issue that I am having is that it removes and adds some rows but won't remove or add some rows that it needs to until after I keep reloading the webpage. Object1 and Object2 are stored before the page unloads. I can add some of my code but I can't add too much since I need to keep the specifications of this project private.Brockie
Maybe the issue is that I am using chrome.storage.local and not chrome.storage.sync?Brockie
@NoahTanenholtz It is not clear what you're trying to do. I don't think that using local instead of sync is the problem, you can learn how storage works form the documentation, this is just basic javascript, using callback functions and checking an object's properties.Bono
it's a little difficult to explain what I am trying to do with my chrome extension since I need to keep specifications a secret and it's used for a specific website. But this code does work for trying to get two key-value pairs simultaneously with the chrome.storage API.Brockie
L
36

You can use new Promise, async/await to handle this. Let's say that you want to handle chrome.storage.local.get synchronously so that continueCode() can has the needed data.

Get data:

  const readLocalStorage = async (key) => {
    return new Promise((resolve, reject) => {
      chrome.storage.local.get([key], function (result) {
        if (result[key] === undefined) {
          reject();
        } else {
          resolve(result[key]);
        }
      });
    });
  };

Main function:


async function getData() {
    let key1 = await readLocalStorage('key1');
    object1.innerHTML = key1;
    let key2 = await readLocalStorage('key1');
    object1.innerHTML = key2;

    continueCode();
}

or if you're not familiar with async/await behavior. You could wrap those 2 promises into an array and use Promise.all, like so:

function getData() {
    const key1 = readLocalStorage('key1');
    const key2 = readLocalStorage('key2');

    Promise.all([key1, key2]).then(values => {
        object1.innerHTML = values[0];
        object2.innerHTML = values[1];

        continueCode();
    });
}
Lordling answered 22/12, 2019 at 2:12 Comment(5)
I needed new Promise, not just Promise.Veery
function async getData() gave me an error. Changing the code to async function getData() resolved itYnez
Getting an "uncaught exception: undefined" error pointing at the very last closing bracket of the getData() function.Cloudland
kind of magical with JavaScript's stacktrace right? :D. Just check the brackets and syntax @FMazLordling
@ToanQuocHo the issue was that the promise failed (as the first time, the key did not exist in local storage, so the promise failed) and the code did not have a catch clause.Cloudland
M
0

https://developer.chrome.com/docs/extensions/reference/storage/#asynchronous-preload-from-storage has an example of getting chrome storage asynchronously. They use the following function. (I modified it to be able to return any top keys)

function getAllStorageSyncData(top_key) {
  // Immediately return a promise and start asynchronous work
  return new Promise((resolve, reject) => {
    // Asynchronously fetch all data from storage.sync.
    chrome.storage.local.get(top_key, (items) => {
      // Pass any observed errors down the promise chain.
      if (chrome.runtime.lastError) {
        return reject(chrome.runtime.lastError);
      }
      // Pass the data retrieved from storage down the promise chain.
      resolve(items);
    });
  });
}

// It can be called like this:
var obj = await getAllStorageSyncData(['key','key2']);
// obj will have obj.key and obj.key2

Put null as the top key to return all keys.

Mendacious answered 12/7, 2022 at 6:24 Comment(0)
A
0

Here is a simplified answer to achieve this if you can change getData to async:

async function getData() {
    var result = await chrome.storage.local.get('key');
    if (Object.values(result)[0] != undefined) {
        object1.innerHTML = Object.values(result)[0].val;
    }

    result = await chrome.storage.local.get('key2')
    if (Object.values(result)[0] != undefined) {
         object2.innerHTML = Object.values(result)[0].val;
    }

    continueCode();
}

The important part is you can simply await the result.

result = await chrome.storage.local.get(key);

Note: You can get both data from key1 and key2 in one call by passing them together into the array

Aphaeresis answered 25/7, 2024 at 7:23 Comment(0)
B
-2

You need to wait for both callback function that you pass to chrome.storage.local.get(..) to be executed before you call continueCode(), also, you can check both storage properties with a single call, here is an example:

function getData() {
  chrome.storage.local.get(['key', 'key2'], function(result) {
    if (typeof result.key !== 'undefined') {
      object1.innerHTML = result.key.val;
    } 
    if (typeof result.key2 !== 'undefined') {
      object2.innerHTML = result.key2.val;
    } 
    continueCode();
  }
}
Bono answered 22/12, 2019 at 2:2 Comment(7)
I was having some trouble with storing and getting objects of two different keys, but I'll try this out.Brockie
so continueCode() will execute immediately after the if conditionals are checked (and if they are true) and the innerHTML of the object is set, because in my continueCode() I get object1 or object2 from the HTML by calling document.getElementById()Brockie
@NoahTanenholtz No, continueCode() will be executed no matter if the properties are set or not.Bono
The issue that I'm having is that object1 is a table and I need to remove, add, and sort rows from the table. I need to be able to do this after the object1.innerHTML is set and updated, the issue that I am having is that it removes and adds some rows but won't remove or add some rows that it needs to until after I keep reloading the webpage. Object1 and Object2 are stored before the page unloads. I can add some of my code but I can't add too much since I need to keep the specifications of this project private.Brockie
Maybe the issue is that I am using chrome.storage.local and not chrome.storage.sync?Brockie
@NoahTanenholtz It is not clear what you're trying to do. I don't think that using local instead of sync is the problem, you can learn how storage works form the documentation, this is just basic javascript, using callback functions and checking an object's properties.Bono
it's a little difficult to explain what I am trying to do with my chrome extension since I need to keep specifications a secret and it's used for a specific website. But this code does work for trying to get two key-value pairs simultaneously with the chrome.storage API.Brockie

© 2022 - 2025 — McMap. All rights reserved.