aQwus jargon
aQwus jargon

Reputation: 133

array doesn't get stored in `localStorage` on using `callback`

I am trying to store item in an array, newItemList, along with present hour and an object, which I get from a server as JSON response, which I parse into a js object. This simply means that a typical element of newItemList will be [item, 13(present_hour), obj]

Here's the code,

 var item;
 //some code to obtain item

 chrome.storage.local.get({'itemList':[]}, function(item){
   var newItemList = item.itemList;
   var d = new Date();

   if (isItemInArray(newItemList,item) == -1) {
     //api call function as callback

     apiCall(function(result){
         newItemList.push([item,d.getHours(),result]);
     });

   } else {
     var indexOfitem = findItem(newItemList,item);//finding item in the array
     if(//some condition){

       apiCall(function(result){
           newItemList[indexOfTab][1] = d.getHours();
           newItemList[indexOfTab][2] = result;
       });

     } else {
       var indexOfitem = findItem(newItemList,item);
       storedApiCall(newItemList[indexOfTab][2]);//sending the stored JSON response
     }
  }
 chrome.storage.local.set({itemList: newItemList});
 })

 function apiCall(callback){
    //API call, to obtain the JSON response from the web server
   var xhttp = new XMLHttpRequest();
   xhttp.onreadystatechange = function() {
   if (this.readyState == 4 && this.status == 200) {
     var myObj = JSON.parse(this.responseText);//parsing the JSON response to js object

      callback(myObj);
      storedApiCall(myObj);//this function just works fine
     }
    };
  xhttp.open("GET", "example.com", true);
  xhttp.send();
 }

newItemList isn't getting stored in local storage. It contains of only one element, [item, present hour, obj(from present apiCall)]. That's why, only the if part of the code runs each time leading to api calls each time, rendering the else part obsolete.

I read about callback from many famous questions asked around about asynchronous calls, but none connected local storage with callbacks. Before implementing callback, newItemList got stored in local storage, but I couldn't obtain the obj from JSON response for the first time, which is the typical behaviour of asynchronous calls. Suggest edits, if any.

Upvotes: 0

Views: 211

Answers (2)

segito10
segito10

Reputation: 388

I think that when the execution arrives on the chrome.storage.local.set({itemList: newItemList}); line, the variable is not set yet because the XMLHttpRequest is async you have to add an chrome.storage.local.set in your callback function or use a promise then set your local storage value

Upvotes: 1

sdgluck
sdgluck

Reputation: 27237

This line is being executed before the functions given to your calls to apiCall are invoked (i.e. with its initial value item.itemList):

chrome.storage.local.set({itemList: newItemList});

This is because callbacks are typically invoked after some asynchronous action completes. In your case, they will be invoked after whatever operation apiCall performs is complete, e.g. an HTTP response to an API is received.

So if you move that line into those callback functions, at their end after you have mutated newItemList, the set call on chrome.storage.local will be performed with the changes applied (e.g. newItemList.push([item,d.getHours(),result])):

chrome.storage.local.get({'itemList':[]}, function(item){
    var newItemList = item.itemList;
    var d = new Date();

    if (isItemInArray(newItemList,item) == -1) {
      //api call function as callback

      apiCall(function(result){
          newItemList.push([item,d.getHours(),result]);
          chrome.storage.local.set({itemList: newItemList});
      });

    } else {
      var indexOfitem = findItem(newItemList,item);//finding item in the array
      if(//some condition){

        apiCall(function(result){
            newItemList[indexOfTab][1] = d.getHours();
            newItemList[indexOfTab][2] = result;
            chrome.storage.local.set({itemList: newItemList});
        });

      } else {
        var indexOfitem = findItem(newItemList,item);
        storedApiCall(newItemList[indexOfTab][2]);//sending the stored JSON response
      }
    }
})

Upvotes: 1

Related Questions