John Boe
John Boe

Reputation: 3611

Why storage.set / storage.get fails to set/get data in Chrome?

I am starting to learn to debug extension in Chrome. I have this problem in Chrome but in Firefox webextensions there is not problem. The problem is that in Chrome I cannot get the data which has been saved to storage.

I have this function in background script. I add breakpoint to line with storage.set . I restart addon and I can access all the data in MyNamespace.data... The addon prints notification that installation was successfull, but the log shows empty object when I try to get data.

MyNamespace.checkIfExists = function (item) {
  if (chrome.runtime.lastError) {
    MyNamespace.notify("check-fail");
    console.log("error:" + chrome.runtime.lastError);
    console.log(chrome.runtime.lastError);
  } else {
    if ( ! ( "initiated" in item ) )
      {
      console.log("I'm initiating .. item:");
      console.log(item);
      /* Insert new data object */
      /* This saves default values into storage */       
      chrome.storage.local.set({
        easy:     MyNamespace.data.easy,
        advanced: MyNamespace.data.advanced,
        images:   MyNamespace.data.images,
        inspector:MyNamespace.data.inspector,
        extractor:MyNamespace.data.extractor,
        profiles: MyNamespace.data.profiles,
        default_profiles: MyNamespace.data.default_profiles        
        }, 
        () => {
          if (chrome.runtime.lastError) 
            { 
            MyNamespace.notify("write-fail");            
            console.log("local.set Error: " + chrome.runtime.lastError); }
          else
            {                         
            MyNamespace.notify("write-succeess");
            chrome.storage.local.get( {initiated: undefined, easy:undefined}, 
              (result) => {
                if (typeof result === undefined )
                  MyNamespace.notify("write-fail");
                console.log("found:");
                console.log(result);
                console.log("/end");
                }
              )
            chrome.storage.local.set( {initiated:true} );            
            MyNamespace.initiated = true;
            }
        } );
      }
    else
      MyNamespace.initiated = true;
  }
};

Result in console:

I'm initiating .. item:
namespace.js:125 Object {}
namespace.js:149 found:
namespace.js:150 Object {}
namespace.js:151 /end

No error in console. In Chrome the object is empty. In Firefox I see one object to be saved, one property to be undefined.

manifest.json

{
  "applications": {
  "gecko": {
    "id": "[email protected]",
    "strict_min_version": "48.0a1"
    }
  },
"description": "An example options ui",
"homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/favourite-colour",
"manifest_version": 2,
"name": "Favourite colour",
"version": "1.0",
"icons": {  
  "48": "icons/eye-icon-colored-48.png"    
},
"options_ui": {
  "page": "options.html",
  "open_in_tab": true
  },
"browser_action": {
  "default_title": "Adapt page",
  "browser_style": true,
  "default_popup": "popup/settings.html",
  "default_icon": {
    "48": "icons/eye-icon-48.png"
  }
},
"web_accessible_resources": [
  "icons/hotkeys-icon-32.png"
  ],
"permissions": ["storage", "tabs", "activeTab", "notifications"],
"background": {
  "page": "background_scripts/background_scripts_bug_fix.html"
 },
"content_scripts": [
    {
    "matches": ["<all_urls>" ],
    "run_at": "document_start",
    "js": [
      "content_scripts/jquery-3.0.0.js",
      "content_scripts/namespace.js",
      "content_scripts/easy.js",
      "content_scripts/addListeners.js"
      ]
    }
  ],
"commands": {
  "easy": {
    "suggested_key": {
      "default": "Ctrl+Shift+U"    
    },
    "description": ""
  }
 }
}

I have added this listener to be fired when storage data are saved:

chrome.storage.onChanged.addListener(function(changes, namespace) {
  for (key in changes) {
    var storageChange = changes[key];
    console.log('Storage key "%s" in namespace "%s" changed. ' +
                'Old value was "%s", new value is "%s".',
                key,
                namespace,
                storageChange.oldValue,
                storageChange.newValue);
  }
});

And I got this log:

    namespace.js:241 Storage key "default_profiles" in namespace "local" changed. Old value was "Object", new value is "undefined".
    namespace.js:241 Storage key "easy" in namespace "local" changed. Old value was "Object", new value is "undefined".
    namespace.js:241 Storage key "extractor" in namespace "local" changed. Old value was "Object", new value is "undefined".
    namespace.js:241 Storage key "images" in namespace "local" changed. Old value was "Object", new value is "undefined".
    namespace.js:241 Storage key "initiated" in namespace "local" changed. Old value was "true", new value is "undefined".
    namespace.js:241 Storage key "inspector" in namespace "local" changed. Old value was "Object", new value is "undefined".
    namespace.js:241 Storage key "profiles" in namespace "local" changed. Old value was "Object", new value is "undefined".
    namespace.js:124 I'm initiating .. item:
    namespace.js:125 Object {}
    namespace.js:241 Storage key "advanced" in namespace "local" changed. Old value was "undefined", new value is "Object".
    namespace.js:241 Storage key "default_profiles" in namespace "local" changed. Old value was "undefined", new value is "Object".
    namespace.js:241 Storage key "easy" in namespace "local" changed. Old value was "undefined", new value is "Object".
    namespace.js:241 Storage key "extractor" in namespace "local" changed. Old value was "undefined", new value is "Object".
    namespace.js:241 Storage key "images" in namespace "local" changed. Old value was "undefined", new value is "Object".
    namespace.js:241 Storage key "inspector" in namespace "local" changed. Old value was "undefined", new value is "Object".
    namespace.js:241 Storage key "profiles" in namespace "local" changed. Old value was "undefined", new value is "Object".
    namespace.js:152 found:
    namespace.js:153 Object {}
namespace.js:154 /end
namespace.js:241 Storage key "initiated" in namespace "local" changed. Old value was "undefined", new value is "true".

So what does this mean? I see word Object() in Chrome, white letters (Dark Theme) but it is not like link where I could click and see the object. This shows the data are loaded. But why I cannot watch the data in the Object?

  1. I cannot step into the callback so I cannot watch the data
  2. I cannot watch what is in the Object {} in Console.... it looks like it is empty but in listener I got messages storage has been changed.
  3. result in storage.get callback result is empty ... contains no properties

I have checked it with this code: for (var key in result) if (hasOwnProperty.call(result, key)) console.log("key:" + key);

In Chrome no properties are listed, in Firefox Toolbox / Console they are listed.

As far as I understand the storage.set callback it should be fired after the save changes has been made and the db file is closed for write. So I expect that there shouldn't be any problem in storage.get fired from inside storage.set

Can someone clarify what is happen here? Why in Firefox this works, but in Chrome no? How to fix the problem?

Upvotes: 0

Views: 1007

Answers (1)

woxxom
woxxom

Reputation: 73506

chrome.storage.local.get( {initiated: undefined, easy:undefined},

Will get nothing because only defined keys are retrieved (1, 2) using intermediate stringification of the parameters object: JSON.stringify({a:undefined,b:undefined}) produces '{}' - it's empty.

Instead use an array of key names when you don't provide default values:

chrome.storage.local.get( ['initiated', 'easy'], 

P.S. use %o or %O in console.log format string to show actual contents of objects.

Upvotes: 2

Related Questions