7

I'm building a chrome extension and have encountered a bug I cannot wrap my head around. The problem is a single object property that becomes null in chromes' storage.

I'm testing this by doing:

console.log("pre-storage", settings);
var obj = {};
obj[storage_key] = settings;

chrome.storage.sync.set(obj, function() {
    chrome.storage.sync.get(storage_key, function(data) {
        console.log("post-storage", data[storage_key]);
    });
});

This is the output:

pre-storage, Object {
    ...
    soundClip: Object {
        options: Array[5],
        selected: Object {
            label: "Soft2",
            value: "snd/soft2.wav"
        }
    }
}

post-storage, Object {
    ...
    soundClip: Object {
        options: Array[5],
        selected: null
    }
}

Storing JSON.parse(JSON.stringify(obj)) instead of obj directly seems to fix this. Anyone have any ideas what might cause this? Any help is appreciated!

Edit: Making a deep copy of obj does not fix it.

Edit2: I should expand on how settings.soundClip is set. I'm using Angular (1.x) and I'm using a custom select directive. The stripped down directive looks like this:

function mySelect() {
    return {
        restrict: "E",
        templateUrl: "mySelect.html",
        scope: {
            options: "=",
            selected: "="
        },
        link: function (scope) {
            scope.select = function (item) {
                scope.selected = item;
            };
        }
    }
}

Directive template view (mySelect.html):

<div>
    <div ng-repeat="item in options track by $index"
         ng-click="select(item)">
    </div>
</div>

The properties are then two-way bound like this:

<my-select selected="settings.soundClip.selected"
           options="settings.soundClip.options">
</my-select >
Easypeasy
  • 150
  • 2
  • 11

2 Answers2

0

Since calling JSON.parse(JSON.stringify(obj)) seems to fix it, my guess is that you're having a problem with encoding your settings object with a variable instead of a string. See the answer here which might help.

Community
  • 1
  • 1
eholder0
  • 302
  • 3
  • 15
  • Thanks for the reply! Unfortunately, using `"test"` instead of `storage_key` yields the same results. – Easypeasy Jan 27 '16 at 21:17
  • Right, and since you get out the value using storage_key, I assume that works. I would look at how you're putting whatever value into settings.soundClip.selected (or similar dictionary syntax) though since that is the only part that has the problem, just to be clear. Sorry for any confusion. – eholder0 Jan 27 '16 at 21:47
  • Yeah that may be of interest, I have added additional information to the original question! – Easypeasy Jan 27 '16 at 22:05
0

Is it possible that the total quota (or per item) is being hit? Consider displaying the runtime.lastError on the set callback to see if there are any error messages.

chrome.storage.sync.set(obj, function() {

  console.log('Error', runtime.lastError);

  chrome.storage.sync.get(storage_key, function(data) {
    console.log("post-storage", data[storage_key]);
  });
});

See the limits here chrome.storage.sync.set

Pablo Navarro
  • 8,244
  • 2
  • 43
  • 52
  • Hey, thanks for the reply! I doubt it's because I'm hitting a limit, the object is 434 bytes. `chrome.runtime.lastError` is undefined, this is all too weird! – Easypeasy Feb 08 '16 at 23:30
  • 1
    Can you try again, but instead of using the data from Angular, use the values you expect to get from it? It is possible that the serialization of the values is not being correctly done as @eholder0 suggests. – Pablo Navarro Feb 09 '16 at 00:26