Search code examples
javascripthtmlajaxxmlhttprequest

Multiple XMLHttpRequests not working


I am puzzled about this. I have two XMLHttpRequests that operate on Select elements of my HTML file (each one operates on a different Select element right when the HTML file is loaded). I am using a callback function as was recommended on W3CSchools. If my variable xmlHttp is defined outside of my callback function, only the second request works, and the first one gets deleted before it has a chance to finish. If I put 'var' in front of it the same thing happens. However, if my variable is inside the function with 'var' in front of it, then absolutely nothing happens. I have narrowed it down to where to the line that says "HERE!!!!!" is where the program seems to hang. I know the loadXMLDoc function does not actually finish because when I put an alert outside of it, nothing happens. I am supposing it has something to do with the 'if' part and the program not being able to recognize xmlHTTP, even though it was locally defined. I am still pretty new to JavaScript and just want to be able to run multiple XMLHttpRequest objects at once without them getting in each other's way but also without the page hanging. Any ideas why this does not work?

HTML:

<form>

    <select id="stateSelectCities">
        <!-- Will be populated with MySQL -->
    </select>

    <select id="citySelect">
        <option>Select a State</option>
    </select>

    <br />
    <br />

    <select id="stateSelectCounties">
        <!-- Will be populated with MySQL -->
    </select>

    <select id="countySelect">
        <option>Select a State</option>
    </select>

    <p id="xmltest"></p>
    <p id="currentState"></p>
    <p id="sc"></p>
    <p id="rs"></p>
    <p id="st"></p>

</form>

JavaScript:

<script type="text/javascript">
function loadXMLDoc(method, data, url, cfunc) {
            var xmlHTTP = new XMLHttpRequest();
            xmlHTTP.onreadystatechange = cfunc;
            xmlHTTP.open(method, url, true);
            if (data) {
                xmlHTTP.setRequestHeader("Content-type","application/x-www-form-urlencoded");
                xmlHTTP.send(data);
            } else {
                xmlHTTP.send();
            }
        }

function returnStateListForCounties() {
            loadXMLDoc('GET', null, "stateslist.xml", function() {
                document.getElementById('countySelect').disabled = true;
                if (xmlHTTP.readyState == 4 && xmlHTTP.status == 200) {

                    // Read the XML Data and Populate Counties States Menu
                    var response = xmlHTTP.responseXML;
                    var states = response.getElementsByTagName('state');
                    for (i = 0; i < states.length; i++) {
                        var option = document.createElement('option');
                        option.innerHTML = states[i].childNodes[0].nodeValue;
                        option.setAttribute('onmouseup', 'returnCounties(this.innerHTML)');
                        document.getElementById("stateSelectCounties").add(option);
                    }
                }
                //document.getElementById("sc").innerHTML = 'statusCode: ' + xmlHTTP.status;
                //document.getElementById("rs").innerHTML = 'readyState: ' + xmlHTTP.readyState;
                //document.getElementById("st").innerHTML = 'statusText: ' + xmlHTTP.statusText;

            })
        }

function returnStateListForCities() {
            loadXMLDoc('GET', null, 'stateslist.xml', function() {
                document.getElementById('citySelect').disabled = true;
                // HERE!!!!!
                if (xmlHTTP.readyState == 4 && xmlHTTP.status == 200) {

                    // Read the XML Data and Populate Cities States Menu
                    var response = xmlHTTP.responseXML;
                    var states = response.getElementsByTagName('state');
                    for (i = 0; i < states.length; i++) {
                        var option = document.createElement('option');
                        option.innerHTML = states[i].childNodes[0].nodeValue;
                        option.setAttribute('onmouseup', 'returnCities(this.innerHTML)');
                        document.getElementById("stateSelectCities").add(option);
                    }
                }
                document.getElementById("sc").innerHTML = 'statusCode: ' + xmlHTTP.status;
                document.getElementById("rs").innerHTML = 'readyState: ' + xmlHTTP.readyState;
                document.getElementById("st").innerHTML = 'statusText: ' + xmlHTTP.statusText;

            })
        }

//returnStateListForCounties();
returnStateListForCities();

</script>

Solution

  • The problem here is xmlHTTP variable which is defined inside loadXMLDoc function and try to use again inside returnStateListForCounties function, I'll do it like this:

           function loadXMLDoc(method, data, url, cfunc) {
                var xmlHTTP = new XMLHttpRequest();
                xmlHTTP.onreadystatechange = function() {
                    if (xmlHTTP.readyState == 4 && xmlHTTP.status == 200)
                    {                         
                        cfunc(xmlHTTP.responseXML); //Call passed func with the resulting XML
                    }
                };
    
                xmlHTTP.open(method, url, true);
                if (data) {
                    xmlHTTP.setRequestHeader("Content-type","application/x-www-form-urlencoded");
                    xmlHTTP.send(data);
                } else {
                    xmlHTTP.send();
                }
            }
    

    This way you encapsulate the data recovery.