Ivan Martinyuk Ivan Martinyuk - 9 days ago 8
Javascript Question

Why does chrome.storage.local save only the last record?

I am writing a Chrome extension in which I need to save data in

chrome.storage.local
. But, it saves only last record data. Can you explain me what am I doing wrong?

Ordinary localStorage is bad, because after resetting settings in the Chrome browser, localStorage is empty.

chrome.runtime.onMessage.addListener(function (request) {
if (request.type === 'setInLocalStorage') {
var key = request.key;
//alert(key);

chrome.storage.local.set({key: request.data},function () {
alert('data was saved');
});

}
return true;
});
chrome.runtime.onMessage.addListener(function (request, sender, SendResponse) {
if (request.type === 'getFromStorage') {
chrome.storage.local.get(null, function (items) {
var allKeys = Object.keys(items);
if (allKeys.length != 0) {
for (var i = 0; i < allKeys.length; i++) {
alert(items[allKeys[i]]);
if (items[allKeys[i]] === request.value) {
SendResponse(true);
} else if (i === allKeys.length - 1) {
SendResponse(false);
}
}
} else {
SendResponse(false);
}
});
}
return true;
});

Answer

Only the most recently saved value exists in storage.local, because you repeatedly store all values into the property 'key', which is overwritten each time you call chrome.storage.set(). Basically, you are not creating the Object you think you are for your call to chrome.storage.set().

You use the Object literal/Object initializer as:

{key: request.data}

This is equivalent to:

{'key': request.data}

It does not substitute in the value of the variable key. So, every time you attempt to save, you are storing the data in the property 'key', not the key which you are passing in the message (i.e. request.key).

You can use a computed property name directly within the Object initializer which you are already using:

{[key]: request.data}

This results in the contents of the variable key being used as the property to which to assign the value of request.data.

Which would make your code:

chrome.runtime.onMessage.addListener(function (request) {
    if (request.type === 'setInLocalStorage') {
        var key = request.key;
        //alert(key);

        chrome.storage.local.set({[key]: request.data},function () { //only this line changes
            alert('data was saved');
        });
    }
    return true;
});

Alternately, you can do the same thing, but a bit more verbose, by first creating the object and then setting the property:

chrome.runtime.onMessage.addListener(function (request) {
    if (request.type === 'setInLocalStorage') {
        var setObject = {};
        setObject[request.key] = request.data;
        //alert(key);

        chrome.storage.local.set(setObject,function () {
            alert('data was saved');
        });
    }
    return true;
});