0

When retrieving a complex JSON object from chrome.storage.local the object is breaking.

mock.json

{
"ThingOne" : [
    "a", 
    "b"
],
"ThineTwo" : [
    "a", 
    "b"
],
"People" : {
    "FamilyOne" : {
        "AgeOne" : "3",
        "AgeTwo" : "8"
    }
},
"Hats" : ["blue", "red", "green"]

}

and I am fetching this file (correctly) using

    fetch('./mock.json').then(response => {
      console.log(response);
      return response.json();
    }).then(data => {
        //data == the whole json file

        var data2 = JSON.stringify(data);
        chrome.storage.local.set({'StoredJson': data2});

        //here this is the result of this code
        //console.log(data2.ThingOne[0]);
        //outputs => "a"

    
    }).catch(err => {
        console.log("Error Reading data " + err);
    });
    
    waitfunction();
    chrome.storage.local.get('StoredJson', function(result) {
        console.log("from get ------"); //outputs below
        console.log(result); //{Data: ""{\"ThingOneOne\":[\"a\",\"b\"],\...
        console.log(typeof result); //object
        console.log(typeof result.ThingOne);//undefined
        //https://i.stack.imgur.com/SUmkq.jpg
    });  

Why is it working when I fetch the object but not when I retrieve it. I have tried storing it after JSON.stringifying it. And I have tried to use it after JSON.parsing it which returns

VM6:1 Uncaught SyntaxError: Unexpected token o in JSON at position 1 at JSON.parse ()

indicating that it is already a JS object. I have tried using dot notation and bracket notaion it doesn't work. When I store it in the chrome console as var data = {//json here} it works. But not live. StackOverflow: Save json to chrome storage / local storage hasn't helped me. Picture of console

Yunnosch
  • 26,130
  • 9
  • 42
  • 54
  • You don't need to stringify an object before storing it in `chrome.storage`. You can do this directly: `chrome.storage.local.set({'StoredJson': data})`. – Iván Nokonoko Nov 17 '20 at 10:22

1 Answers1

0

There are multiple problems in the code.

  1. There's no need for JSON.stringify. Just store the data directly.

  2. Both fetch and chrome.storage are asynchronous so your chrome.storage.local.get will run before the data is set and it won't see the correct data.

  3. waitfunction(); won't wait for anything, it won't influence asynchronous code before it or afterwards.

  4. chrome.storage.local.get('StoredJson', callback) reads the data into an object property named StoredJson i.e. you can read the value as result.StoredJson.

Overall, a proper modern solution is to switch to async/await:

(async () => {
  try {
    const data = await (await fetch('./mock.json')).json();
    console.log('Fetched', data);
    await writeStorage({StoredJson: data});
    const {StoredJson} = await readStorage('StoredJson');
    console.log('Stored', StoredJson);
  } catch (err) {
    console.log(err);
  }
})();

function readStorage(key) {
  return new Promise(resolve => {
    chrome.storage.local.get(key, resolve);
  });
}

function writeStorage(data) {
  return new Promise(resolve => {
    chrome.storage.local.set(data, resolve);
  });
}
wOxxOm
  • 65,848
  • 11
  • 132
  • 136
  • TL;DR #4 was the main issue. Thank you for your response. 1. I have tried every combination of JSON.stringify and JSON.parse, and I was trying to convey that but I didn't, that's my fault. 2. I understand they are asynchronous. I have a messy settimeout system right now in my real code that works, I was trying to simplify that for the problem. 3. assuming the wait function works shouldn't that prevent the code from running after it?. 4. Yes I was screwing that up, I have fixed that but now as I read the object it is of typeof string. JSON.parse fixed it. (2 day frustrating bug, sincerely ty – TheIrishPizzaGuy Nov 17 '20 at 22:20