Nested XMLHttpRequests in extension not working

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?

1 thought on “Nested XMLHttpRequests in extension not working”

  1. Your problem is that you are using chrome.tabs.query in two different ways. From the docs chrom.tabs.query(queryInfo, callback) (Chrome Dev) takes as callback a function with a parameter of type Tab (Chrome Dev) which is not iterable.

    The first time you used it well:

    // "tab" as *singular*
    chrome.tabs.query({currentWindow: true, active: true}, function (tab) { // <-- here 
          chrome.tabs.update(tab.id, {url: page});
    });
    

    But the second time you used it like an array:

    // "tabs" as *plural*?
    chrome.tabs.query({active: true, lastFocusedWindow: true}, tabs => { // <-- here
          var current_url = tabs[0].url; // <-- tabs[0] is not defined!
          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");
    });
    

    A Tab object has no attribute '0' so by accessing tabs[0] you are actually retriving an undefined, which throws the error on the url property access

    Reply

Leave a Comment