The following reads data from a json file generated by a database call.
function loadJSON(callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', 'next.php', true);
xobj.onreadystatechange = function () {
if (xobj.readyState == 4 && xobj.status == "200") {
callback(JSON.parse(xobj.responseText));
}
};
xobj.send(null);
}
The following uses the above function to select a random url and change the url when user clicks button.
var page = '';
var nextpageButton = document.getElementById('nextpage');
nextpageButton.addEventListener('click', function() {
loadJSON(function(json) {
var limit = json.length;
var i = ((Math.floor(Math.random()*limit)+1) - 1);
page = (json[i].sites);
chrome.tabs.query({currentWindow: true, active: true}, function (tab) {
chrome.tabs.update(tab.id, {url: page});
});
});
});
Both above functions work perfectly.
The following adds data to databse when the user clicks button. This works perfectly as long as I don’t add a nested XMLHttpRequest on success.
var like = document.getElementById('tu');
like.addEventListener('click', function() {
var select_element = document.getElementById('cat');
var cat = select_element.value;
if (cat != 0) {
chrome.tabs.query({active: true, lastFocusedWindow: true}, tabs => {
var current_url = tabs[0].url;
var current_title = tabs[0].title;
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "add.php", true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send("sites="+current_url+"&title="+current_title+"&vote_up=1&vote_down=0");
});
} else {
select_element.focus();
}
});
Things start to break when I add the following to the above code:
//this is the last row from above code before adding new code
xhttp.send("sites="+current_url+"&title="+current_title+"&vote_up=1&vote_down=0");
//this is new code
xhttp.onreadystatechange = function() {
if(xhttp.readyState == 4 && xhttp.status == 200) {
loadJSON(function(json) {
var limit = json.length;
var i = ((Math.floor(Math.random()*limit)+1) - 1);
page = (json[i].sites);
chrome.tabs[0].update(tab.id, {url: page});
});
}
}
When I add the above code, which should just be calling the first function, I start getting javascript error Cannot read property 'url' of undefined
.
Se the question is… if javascript reads in a linear manner from top to bottom, why would the property become undefined with the addition of the loadJSON(function(json)
? I can remove that function and everything works again. This is not a variable that is defined by the XMLHttpRequest so why would a nested request stop the variable from being loaded correctly?
More important how do I fix this?
Your problem is that you are using
chrome.tabs.query
in two different ways. From the docschrom.tabs.query(queryInfo, callback)
(Chrome Dev) takes ascallback
a function with a parameter of typeTab
(Chrome Dev) which is not iterable.The first time you used it well:
But the second time you used it like an array:
A
Tab
object has no attribute'0'
so by accessingtabs[0]
you are actually retriving anundefined
, which throws the error on theurl
property access