Reputation: 655
I'm building a firefox web extension and I'd like to give its users some options that they can check/uncheck. The state of the checkboxes is saved locally via the WebExtensions storage API, but I'm not quite sure how to restore the saved state for each option.
Here is the options.html file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<form method="post">
<fieldset>
<legend>My favorite veggies</legend>
<input type="checkbox" name="eggplant" id="eggplant" />Eggplant<br />
<input type="checkbox" name="zucchini" id="zucchini" />Zucchini<br />
<input type="checkbox" name="tomatoe" id="tomatoe" />Tomatoe<br />
<input type="submit" value="Submit" />
</fieldset>
</form>
<script src="options.js"></script>
</body>
</html>
The options.js file that saves/restores the state of the checkboxes is as follows:
function onError(error) {
console.log(`Error: ${error}`);
}
function saveOptions(e) {
// List of search engines to be used
let eggplant = {
name: "Eggplant",
imageUrl: "https://www.organicfacts.net/wp-content/uploads/2013/06/Eggplant-1020x765.jpg",
show: form.eggplant.checked
};
let zucchini = {
name: "Zucchini",
imageUrl: "https://www.organicfacts.net/wp-content/uploads/zucchini.jpg",
show: form.zucchini.checked
};
let tomatoe = {
name: "Tomatoe",
imageUrl: "https://www.organicfacts.net/wp-content/uploads/2013/05/Organictomato1-1020x765.jpg",
show: form.tomatoe.checked
};
let setting = browser.storage.sync.set({
eggplant,
zucchini,
tomatoe
});
setting.then(null,onError);
e.preventDefault();
}
function restoreOptions() {
var gettingItem = browser.storage.sync.get({
'show'
});
gettingItem.then((res) => {
document.getElementById("eggplant").checked = eggplant.show;
document.getElementById("zucchini").checked = zucchini.show;
document.getElementById("tomatoe").checked = tomatoe.show;
});
}
document.addEventListener('DOMContentLoaded', restoreOptions);
document.querySelector("form").addEventListener("submit", saveOptions);
Upvotes: 0
Views: 216
Reputation: 77523
Here's the state of your storage after the set
operation:
{
eggplant: {
name: "Eggplant",
imageUrl: "https://www.organicfacts.net/wp-content/uploads/2013/06/Eggplant-1020x765.jpg",
show: true
},
zucchini: { /* ... */ },
tomatoe: { /* ... */ }
}
However, in restoreOptions
, you query the storage with the key "show"
- or, more specifically, with a syntactically incorrect object literal {"show"}
.
Even if you fix it to be "show"
is no such top-level key (and that's the only type of query you're allowed), so the result comes up as empty.
null
.Here's how to organize your code with using defaults:
const defaults = {
eggplant: {
name: "Eggplant",
imageUrl: "(redacted for brevity)",
show: false
},
zucchini: {
name: "Zucchini",
imageUrl: "(redacted for brevity)",
show: false
},
tomatoe: {
name: "Tomatoe",
imageUrl: "(redacted for brevity)",
show: false
}
};
function saveOptions() {
let settings = {}
for (let setting in defaults) {
settings[setting] = {
...defaults[setting], // spread the default values
show: form[setting].checked // override show with real data
}
}
browser.storage.sync.set(settings).then(null, onError);
}
function restoreOptions() {
browser.storage.sync.get(defaults).then(
(data) => {
document.getElementById("eggplant").checked = data.eggplant.show;
document.getElementById("zucchini").checked = data.zucchini.show;
document.getElementById("tomatoe").checked = data.tomatoe.show;
}
);
}
Of note: don't use submit
and preventDefault
, just use type="button"
inputs and click
.
Small edit: Object spread (...defaults[setting]
) is still experimental (though supported in recent Chrome/FF), a more ES6-compliant code would be
for (let setting in defaults) {
// shallow copy default settings
settings[setting] = Object.assign({}, defaults[setting]);
// override show property
settings[setting].show = form[setting].checked;
}
Less concise, somewhat more compatible.
Upvotes: 1