Initialization of extension settings

I was looking at this solution for initializing user options of an add-on on Stackoverflow: https://stackoverflow.com/questions/23638777/provide-initial-settings-for-chrome-extension/23638867#23638867

chrome.storage.local.get({option: "default"}, function(data){
  chrome.storage.local.set(data, /*...*/);
});

When does the set function execute?

My intention is to set the default values of the options variables during the onInstalled event in the background script, but obviously I wish to avoid resetting them during a browser version update or during an update of the add-on’s version itself.

You could check the “reason” property in the onInstalled event to see if it’s update or new install: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/OnInstalledReason

But I would say a better approach would be to check if the storage has the value and if not, set it to default. You can then put the code to the root of the background script so that it’s called every time your extension starts.

Why would this be better? Because if you decide one day to add more settings with some new default values, your code can detect missing default values and add them to the storage.

Does the solution from Stackoverflow works as it says it does? When does the set function execute in that code?

Yeah, the StackOverflow solution would also work. The main idea in that solution is to load all settings which needs default values (while providing those default values) and then simply store it back. So if the values were missing, they will be stored and if they were already there, they won’t change anyway.
And again you can execute it anytime, so for example in the background script if you have one.

Doesn’t the callback function execute every time? If yes, then it would overwrite the stored settings anyway.

Nope, the chrome.storage.local.get loads current values. And if you provide default values, it will be used if those values are missing. And then store it back in, so missing values will be no longer missing and existing values will be “replaced” with same existing values, so no change.

Does the chrome.storage.local.get perform the storage of the default values when the values are missing or is it the callback chrome.storage.local.set function which gets executed only when the values are missing? In the first case the callback should not be used at all.

Edit:
The reason I’m asking is because using the following code:

browser.runtime.onInstalled.addListener(function () {
    browser.storage.sync.get({
        option: "default",
    }, function () {
        browser.storage.sync.set({
            option: "default"
        });
    });
});

reset the option variable to default after a version update of Firefox, so definitely the callback function was executed and it overwrote the current value of the variable.

Yes, because you are not using the data pulled from the store, you are just resetting it.
Also, beware of mixing “browser” and “chrome” namespaces - ideally you should use “browser” and if you are targeting also Chrome browser, use this polyfill.

Anyway, this should do what you need:

browser.runtime.onInstalled.addListener(async details => {
  const storeData = await browser.storage.sync.get({
    option: "default",
  });
  await browser.storage.sync.set(storeData);
});

If you need more info, read docs:

Is that because I didn’t use async - await for the get function?

Nope :slight_smile: , it’s because of the missing argument in the “function” callback :slight_smile:. The async/await is a syntactic sugar that helps understanding the code execution flow and you should for sure use it when working with API that uses Promises.

Oh, OK. So the callback function gets executed, but it overwrites the retrieved value.

Yes, because if you call this, it will override value under key “option” and set it to “default”:

I had the false impression that the callback function would not execute at all, if the get function successfully retrieved a value from the storage.