1

Hi I am new to javascript and could use some help modifying this downloadUrl function to return the called xml document.

function downloadUrl(url, callback) {
        var request = window.ActiveXObject ?
            new ActiveXObject('Microsoft.XMLHTTP') :
            new XMLHttpRequest;

        request.onreadystatechange = function() {
          if (request.readyState == 4) {
            request.onreadystatechange = doNothing;
            callback(request, request.status);
          }
        };

        request.open('GET', url, true);
        request.send(null);
      }

This is an example of how I would like to use the function:

    var url = 'http://127.0.0.1:8080/markers.xml';
    function getxml(url){
      var xml = downloadUrl(url, function(data) {
      });
      return xml
    };

Thanks for your help.

MrClean
  • 1,300
  • 2
  • 12
  • 17
  • 2
    Posible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Gerardo Aug 07 '17 at 21:09

1 Answers1

1

One of the main problems with the code you have written in your question is the possible confusion between synchronous and asynchronous requests. Synchronous simply means that any code after your AJAX call will not run until the request is complete. Asynchronous means the JavaScript code after your AJAX call will run, then once the request is complete, it will then callback to the function you gave your request object (the one at request.onreadystatechange).

There are advantages to both synchronous and asynchronous requests, and knowing which method to use can be tricky. Generally, you want to avoid synchronous requests, as they essentially stop the entire HTML document's loading process. The advantage? They don't require any callbacks, which can possibly become confusing. Asynchronous does require callbacks but doesn't delay the HTML document's loading.

In your case, you probably would be fine using a synchronous request, as long as the XML file is not massive, and the only times getxml() and donwloadUrl() were during the initial loading of the page. I have gone ahead and rewritten the downloadUrl() you wrote to accept a third parameter, that being a boolean called async. When it is true, the request will be done asynchronously, and when it is false, it will be done synchronously.

function downloadUrl(url, callback, async) {
  var request = window.ActiveXObject ?
    new ActiveXObject('Microsoft.XMLHTTP') :
    new XMLHttpRequest;

  if (async) {
    request.onreadystatechange = function() {
      if (request.readyState == 4) {
        request.onreadystatechange = doNothing;
        callback(request);
      }
    };
  }

  request.open('GET', url, true);
  request.send(null);

  if (!async)
    return request;
}

/* 
Submit a synchronous request to "markers.xml" callback = null because synchronous requests don't need callbacks.
*/
var xml1 = downloadUrl("markers.xml", null, false).responseText;
console.log(xml1);

/* 
Submit an asynchronous request to "markers.xml"

xml2 would equal "undefined" after the function call because asynchronous requests use callbacks. Instead, the response will be passed to the callback given in the function call.
*/
var xml2;
downloadUrl("markers.xml", function(xhr) {
  // Now xml2 would be the value of the resource requested
  // so put the code that accesses the value inside the callback,
  // or pass the data to another function from within the callback.
  xml2 = xhr.responseText;
  console.log(xml2);
}, true);

Now that downloadUrl() supports both types of requests, we are free to write new code for getxml().

Synchronous:

var url = 'http://127.0.0.1:8080/markers.xml';
function getxml(url){
  var xml = downloadUrl(url, null, false);
  return xml.responseText;
};
var xmlData=getxml(url);
// Use xmlData here

Asynchronous:

var url = 'http://127.0.0.1:8080/markers.xml';
function getxml(url, callback){
  var xml = downloadUrl(url, callback, true);

};
getxml(url, function(xhr) {
    var xmlData=xhr.responseText;
    // Use xmlData here
}

I personally would use an asynchronous request here, as it is a better JavaScript practice and results in a better user-end experience.