views:

82

answers:

2

Hopefully I've just made a dumb oversight, but I can't figure out why the following doesn't work:

$(function() {
var xml;
    $.get(
        "somexml.xml",
        function(data){
            xml = data;
        },
        "xml");
    alert(xml);
});

If I put the alert inside of the callback function, I get back object XMLdocument but if I place it outside of the ajax call, I get undefined.

Since my goal is to have a new DOM to parse, I don't want the entire handling of the XMLdocument to be within the callback function.

I've tried defining the variable outside of the entire onready function, inside at the top (like above) and inside the callback function, all with no luck.

According to Specifying the Data Type for Ajax Requests in the jquery documentation, this should be possible.

+2  A: 

AJAX is defined as Asynchronous JavaScript and XML -- although people use the term for synchronous and non-XML requests too. Nevertheless, asynchronous means that the request will execute on a separate thread. xml is undefined because the following is happening:

Request is sent -> xml var is accessed -> response is received -> data is assigned to xml variable

As you can see, the data received back isn't assigned to the xml var until after you tried to access it. If you just want a separate block for handling the XML data, why not create a separate function and pass it as a parameter?

$(function() {
    $.get(
        "ews_cal_finditem.xml",
        parseXML,
        "xml");
});
function parseXML(data) {
    // This is the callback function
    alert(data);
}

Or even

$(function() {
    $.get(
        "ews_cal_finditem.xml",
        function(data){
            parseXML(data);
        },
        "xml");
});
function parseXML(xml) {
    alert(xml);
}
Andy E
I had a feeling that the asynchronous aspect was involved, but I didn't know that this meant separate threads were in play. Good to know. If I pass the response to an external function, will this allow me to set the XMLdocument object to a global variable? I'll test to find out, but if not, I'm kind of at a loss as to how to free the data.
Anthony
Looks like freeing the xmldocument is still not an option. If I pass the xml object to the outside function, it alerts out as 'xmldocument' but if I set it to the global variable `xmldom` and alert that outside of everything, I get `undefined`. I kind of expected as much, given what you said about threading, but is it really a core feature of ajax that the document is trapped? I even tried passing the contents as a string and had got nothing. I want the DOM of the response to be a global variable so that various functions can traverse it much later. Not possible?
Anthony
One last thing: The underlying goal here is to have xml that I can later use in other ajax request (as SOAP), so loading the xml as text is even an option (at this point) since the object will be sent as POST data later. I wanted the option to tweak the DOM, but it sounds like even if I keep it as a string, I still won't be able to pass the value to a global variable, right?
Anthony
@Anthony, it's not trapped at all, you can set the XMLDocument to a global variable. You just have to make sure that any reference to the variable comes after completion of the AJAX request.
Andy E
@Andy, I'm not sure how to do that without either a) setting an abritrary sleep timer or b) wrapping the entire rest of the script in an if clause. And I'm guessing either of those options are less than fool-proof. The only other option I see is to write out a full `$.ajax` function that sets the variable in a `complete` callback instead of a `success` callback (which is what `$.get` is using when a function is set). But I would think success or complete would be after the request, no?
Anthony
@Anthony: Indeed, success and complete both fire after the request. Your options are to use an interval to check the existence of the data or chain the related functions together, calling them from the callback function to make sure they are executed.
Andy E
I see where I was getting confused. Setting in either complete or success doesn't matter because when I alert it out below the request, there hasn't been a success or complete yet, so it's not set yet. Duh. So if my script is going to use the xml after the initial load, it should be fine. But trying to do it right below is no good as it's still happening in a different thread. Got it. So can I set a global variable to be an ajax function such that it would be set for any subsequent use, or am I back to where I started?
Anthony
@Anthony, you will need to assign the response data to the variable, assigning the ajax function will not help you :-)
Andy E
A: 

You could also run the ajax call as async=false, but this should be done carefully as it will block further execution until it's complete. You have to be careful when you take the A out of AJAX.

ScottE
Good idea, but with the shorthand function `$.get` I would have to set it on a `ajaxSetup()` function, which would make it for ALL requests. I'm getting the distinct impression that I should not use `$.get` for what I want.
Anthony
So call the base method instead!
ScottE