Reputation: 133
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
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
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