3

So after 6+ hours of searching and trying out various solutions, I have only been able to log "undefined" at console.log(diseaseNameArray). I am very new to javascript, and cannot figure out why this is not logging a populated array. I greatly appreciate any help/advice you have to give. Any other additional critiques of code are also appreciated.

var diseaseNameArray;
var jax = $.ajax;

/*OutputHandler*/
function outputHandler(data, arrayTarget, tag, length) {
    var source = $(data); /*holder of xml*/
    var lengthStorage = Number(source.find(length).text()); /*length of list*/
    arrayTarget = []; //array to be populated
    for(i = 1; i < lengthStorage; i++)
    {
        arrayTarget[i] = source.find(tag + i.toString()).text();
        console.log(arrayTarget[i]); //to check that elements are being entered
    }
    console.log(arrayTarget); //succesfully logs the full array
}

/*General function*/
function populateArray(xmlLocation, typeOfData, tag, lengthStorage, extFunction, targetArray) {     
    $.ajax({
        type: "GET",
        url: xmlLocation,
        dataType: typeOfData,
        success: function(xml)
        {
            extFunction(xml, targetArray, tag, lengthStorage);
        },
        error: function()
        {
            console.log("ugh");
        }
    });
}

populateArray("malePatient.xml", "xml", "sub", "length", outputHandler, diseaseNameArray);
console.log(diseaseNameArray);

Update Thanks to Jan's point, I am back at the drawing board to get this to work. If anyone has a suggestion I would greatly appreciate it!

jpat827
  • 114
  • 2
  • 9
  • Jquery's `async=false` option is about to become deprecated, so I'd advise against it. There's also very few real-world applications where it's absolutely necessary. – Jan Jul 06 '15 at 23:37
  • @Jan Thank you for that information, I did not realize how close to the chopping block async = false is. Would you be able to give an example of to implement this properly in this situation? Or even an example of pulling data and using it somewhere other than the success function? After reviewing jQuery documentation over ajax, no light bulbs went off unfortunately. – jpat827 Jul 07 '15 at 04:19
  • Check out the `promises` part of the documentation – Jan Jul 07 '15 at 06:34

3 Answers3

4

Ajax is asynchronous. You are calling populateArray and then immediately logging diseaseNameArray to the console before the ajax request completes, so of course it's going to be undefined -- you're not giving the ajax request time to complete. You need to log to console in success.

Or make the ajax call synchronous with async: false.

Paul Abbott
  • 7,065
  • 3
  • 27
  • 45
  • Paul thank you for your response! I clearly need to dig into the documentation because from reading tutorials I thought success would only run after all of the data had been retrieved. So i am using this array in an in browser game. Is the down side to an asynchronous call simply the page load time? – jpat827 Jul 06 '15 at 21:42
  • 1
    success() will only run after the data has been retrieved, that's correct. But your console.log(diseaseArrayName) is not inside the success function, so the order of events winds up as "go get the data", then "console.log the data that hasn't arrived yet," then "data has arrived, call success()!" – Daniel Beck Jul 06 '15 at 21:52
  • Thanks for your response daniel. I had a typo in that comment. I meant to ask is there a downside to a synchronous call? Are there any immutable rules regarding the use of synchronous over asynchronous? Or is it more subjective. I found this [link](http://stackoverflow.com/questions/14068084/opinion-about-synchronous-requests-in-web-workers). which was helpful, but it has been awhile since that summary was updated. Just wanted to see if there were any generally accepted do and do nots? – jpat827 Jul 06 '15 at 22:39
2

AJAX stands for Asynchronous Javascript And Xml. Because it is asynchronous, your data has not necessarily reached your outputHandler function. You should probably create a function that runs after outputHandler, and is called at the end of outputHandler. You should put your console.log in this second function. That way, it is guaranteed to get the data.

Either that, or you could pass async: false to the AJAX call to make it synchronous, so that the console.log would occur after outputHandler. But, if the AJAX call fails, then console.log would still be called, and it would come out undefined.

Lux
  • 1,540
  • 1
  • 22
  • 28
0

Using this question's answer I was able to create a game function that will be able to access numerous xml documents and utilize the data gathered.

Community
  • 1
  • 1
jpat827
  • 114
  • 2
  • 9