0

I am loading 2 XML documents that both run functions on success, although the function for the 2nd XML document is dependant on the 1st being complete.

If I have async:true:

1st XML

function XmlDataTypes() {

    var result = null;
    var scriptUrl = "http://domain.com/xml/test.XmlDataTypes?AccountId=" + AccountId;
    $.ajax(
    {
        url: scriptUrl,
        type: 'get',
        dataType: 'xml',
        async: true,
        success: function (data) {

        //create array to be used in second XML
       for (var i = 0; i < xmlRows.length; i++) {

                        var dataType = xmlRows[i];

                        var dataTypeId = nodeValue(dataType.getElementsByTagName("DataTypeId")[0]);
                        var dataTypeName = nodeValue(dataType.getElementsByTagName("DataTypeName")[0]);

                        dataTypeArray.push({ dataTypeId: dataTypeId, dataTypeName: dataTypeName, position: i, markerArray: [] });

                    }



        },
        error: function onXmlError() {
            alert("An Error has occurred.");
        }

    });

    return result;

}

2nd XML

function XmlAmenityData() {

    var result = null;
    var scriptUrl = "http://domain.com/xml/test.XmlAmenityData?AccountId=" + AccountId;
    $.ajax(
    {
        url: scriptUrl,
        type: 'get',
        dataType: 'xml',
        async: true,
        success: function (data) {

        //store this info in markerArray in dataTypeArray

        },
        error: function onXmlError() {
            alert("An Error has occurred.");
        }

    });

    return result;

}

The XML data can loaded in a random order so the function for the second document will error if the 1st hasn't completed.

If I set:

async: false

It works correctly but I get a warning:

Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience.

Is there a way around this without using:

async: false

2 Answers 2

4

Since the 2nd xml is dependent on the 1st, you can define a callback on success. Also since ajax is async, you must assign the result when the callback is called. You can define a variable ourside of your function (in this case an array) and put the data there.

var result = [];
function XmlDataTypes(url, accountId, callback) {
    var scriptUrl = url + accountId;
    $.ajax({
        url: scriptUrl,
        type: 'get',
        dataType: 'xml',
        async: true,
        success: function (data) {
             // do something
             result.push(data);
             if(typeof callback == 'function') {
                 callback();
             }
        },
        error: function onXmlError() {
            alert("An Error has occurred.");
        }
    });
}

function doSomething() {
    // Do something to store this info in markerArray in dataTypeArray
    // XmlAmenityData is in results var.
}

And you can use it like so

var _callback = XmlDataTypes("http://domain.com/xml/test.XmlAmenityData?AccountId=", "1234", doSomething);
XmlDataTypes("http://domain.com/xml/test.XmlDataTypes?AccountId=", "1234", _callback);

EDIT: Updated script based on given scenario.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, trying to implement this. but the second XML doc isn't loading, I've updated my code to show how it was before.
dont forget to add the url as param too.
0

You could try to return the $.ajax as a promise:

function XmlDataTypes() {

// note domain.com was changes to example.com - this should be changed back

var scriptUrl = "http://example.com/xml/test.XmlDataTypes?AccountId=" + AccountId;
return $.ajax(
{
    url: scriptUrl,
    type: 'get',
    dataType: 'xml',
    async: true,
    success: function (data) {

    //create array to be used in second XML
   for (var i = 0; i < xmlRows.length; i++) {

                    var dataType = xmlRows[i];

                    var dataTypeId = nodeValue(dataType.getElementsByTagName("DataTypeId")[0]);
                    var dataTypeName = nodeValue(dataType.getElementsByTagName("DataTypeName")[0]);

                    dataTypeArray.push({ dataTypeId: dataTypeId, dataTypeName: dataTypeName, position: i, markerArray: [] });

                }
    },
    error: function onXmlError() {
        alert("An Error has occurred.");
    }

});    

}

Then calling them in sequence :

XmlDataTypes.done(XmlAmenityData);

Here is some more documentation : http://www.htmlgoodies.com/beyond/javascript/making-promises-with-jquery-deferred.html

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.