0

I am trying to save a list of dictionary objects in the chrome storage. But the following code seems to not work as expected.

When the extension loads for the first time and there is no goal object in the storage, runtime.lasterror object should be set and the code in that part should get executed. But it isn't.

When I uncomment the chrome.storage.sync.set line and save the object and the next time I call the function expecting it to save a list, it doesn't. It does not give any of the alert boxes.

function isPgUrl(pg_url,gl_name) {
  if(pg_url && gl_name) {

    dic_url={
      "name":gl_name,
      "pg_url":pg_url
    }

    //chrome.storage.sync.set({"goal":[dic_url]});

    chrome.storage.sync.get(["goal"], function(data) {
      if(chrome.runtime.lastError) {
        chrome.storage.sync.set({"goal":[dic_url]},function() {
          alert("blah");
        });
        alert("here");
        return;
      }
      var list=data.goal;
      list.append(dic_url);
      alert(list);
      chrome.storage.sync.set({"goal":list},function() {
        alert("lalala");
        return;
      });     
    });
  } 
}
Xan
  • 74,770
  • 16
  • 179
  • 206
Ninja Turtle
  • 156
  • 2
  • 18

1 Answers1

1
  1. You'll never get chrome.runtime.lastError set for missing data. It's not an exception - you just get undefined value. So your check should be:

    if(!data.goal) { ... }
    

    or

    if(typeof data.goal === "undefined") { ... }
    
  2. If you uncomment that line, you need to be aware that chrome.storage is asynchronous: the data is not in storage until the callback of .set(). So your .get() that is executed immediately after calling .set() may get a snapshot of the older view of the storage - making your code fail at list.append(dic_url);

    Not that Array.prototype.append exists in the first place. You should be using .push().

  3. Chrome Storage has a more efficient way of setting a default-if-not-in-storage value, by using an Object as a query:

    chrome.storage.sync.get({key: "defaultValue"}, function(data) {
      // data.key will be the stored value, or "defaultValue" if not in storage
    });
    

So, if I understand the purpose of your code correctly (append dic_url to goal in storage), this will do it:

// Makes more sense to default to empty list
chrome.storage.sync.get({goal: []}, function(data) {
  var list = data.goal;
  list.push(dic_url);
  chrome.storage.sync.set({goal: list}, function() {
    // Stoarge updated, dic_url appended to goal
  });
  // Storage is not yet updated - set() is async
});
// Storage is not yet updated - get()/set() are async
Xan
  • 74,770
  • 16
  • 179
  • 206
  • 1
    As an aside, don't use `alert()` for debugging - use `console.log()` and look [in the correct console](http://stackoverflow.com/q/36107503/934239). – Xan Jul 01 '16 at 11:07
  • thanks for the tip @Xan. I am trying the code given by you. Ill let you know asap. – Ninja Turtle Jul 01 '16 at 11:29
  • Be aware I made a typo I just fixed - didn't add a `data` parameter to callback of `get()` – Xan Jul 01 '16 at 11:30
  • I tried your code @Xan with the default empty list. But it is still not working. First time the object is not being appended(on first run of execution). And when i append it by un-commenting the line and try executing your code by commenting it again, it is still not appending it. – Ninja Turtle Jul 01 '16 at 11:34
  • Indeed. Because I trusted you that `append()` is an actual function. It isn't - it should be `push()`. – Xan Jul 01 '16 at 11:36
  • omg!! this was really really stupid!! thanks a lot @Xan. You were of great help. Everything works well now :) – Ninja Turtle Jul 01 '16 at 11:41