Nathan Lundy
Nathan Lundy

Reputation:

Second AJAX call unloading result of the first

Code below is run in the onLoad event of the page. I first would like to populate a drop down menu with getCompany() and then fill in data from the server into text boxes and choose the selected option.

Both functions work, in fact when I reload the page with debugger running and step into everything both do what they are supposed to.

When I just open the page or reload with out debugger the text boxes are filled but the options disappear from the dropdown, why is that?

<script>
        var result;
        function init(){
            var name = window.name;
            name = name.split(",");
            getCompany();
            setTimeout(200);
            if (name[0] = "update"){
                id = name[1];
                getTenant(id);
                //get the info for the line that called the edit function
                //fill fields with information from server
            }
        }

        function getCompany() { 
            if (window.XMLHttpRequest) {
                // code for IE7+, Firefox, Chrome, Opera, Safari
                xmlhttp=new XMLHttpRequest();
            } else { // code for IE6, IE5
                xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
            }
            xmlhttp.onreadystatechange=function x() {
                if (xmlhttp.readyState==4 && xmlhttp.status==200) {
                    document.getElementById("company").innerHTML = xmlhttp.responseText;
                }
            }
            xmlhttp.open("GET","getCompany.php",true);
            xmlhttp.send();
        }

        function getTenant(id){
            if (window.XMLHttpRequest) {
                // code for IE7+, Firefox, Chrome, Opera, Safari
                xmlhttp=new XMLHttpRequest();
            } else { // code for IE6, IE5
                xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
            }
            xmlhttp.onreadystatechange=function y() {
                if (xmlhttp.readyState==4 && xmlhttp.status==200) {
                    result = xmlhttp.responseText;
                    result = result.split(",");
                    //fill the form with old information
                    document.getElementById("fname").value = result[0];
                    document.getElementById("lname").value = result[1];
                    document.getElementById("company").selectedIndex = result[2];
                    document.getElementById("phone").value = result[3];
                    document.getElementById("email").value = result[4];
                    document.getElementById("crm").value = result[5];
                }
            }
            xmlhttp.open("GET","getTenant.php?p=" + id,true);
            xmlhttp.send();
        }
    </script>

Upvotes: 0

Views: 101

Answers (3)

Prabhat Kumar
Prabhat Kumar

Reputation: 310

Make two different object name instead of one (xmlhttp). Like

  • in 'getCompany()' function object name is 'xmlhttp'
  • in 'getTenant()' function changed object name to 'xmlTalenthttp' (or any other name which you wish)

Upvotes: 0

Sampath Liyanage
Sampath Liyanage

Reputation: 4896

I assume the input fields you are filling in data in the second request belong to the data fetched from the first request. I also assume you are using the setTimeout() to delay the 2nd request...

Javascripts are single threaded. To provide asynchronous behavior js uses callback mechanism. After sending a request to the server, js doesn't wait until the response comes. JS keeps executing the rest of code until the results from the server comes. When the response comes from the server the code in the callback function xmlhttp.onreadystatechange is executed. Because of that, both requests may happen at almost the same time and consequently the response for the 2nd request may come before the first response which leads the behavior you see as an error.

When you debug, you execute line by line. Therefore there is enough time to get the response for the first request before getting the response for the second request.

As a solution you can move the code for the second request inside the xmlhttp.onreadystatechange callback in the code for the first request. Then as the callback is always executed after the results are fetched, the second request is sent after the response for the first one comes.

You may google about asynchronous javascript and learn in details...

<script>
    var result;
    function init(){
        var name = window.name;
        name = name.split(",");
        getCompany(name);
    }

    function getCompany(name) { 
        if (window.XMLHttpRequest) {
            // code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp=new XMLHttpRequest();
        } else { // code for IE6, IE5
            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
        }
        xmlhttp.onreadystatechange=function x() {
            if (xmlhttp.readyState==4 && xmlhttp.status==200) {
                document.getElementById("company").innerHTML = xmlhttp.responseText;
                if (name[0] == "update"){
                   id = name[1];
                   getTenant(id);
                   //get the info for the line that called the edit function
                   //fill fields with information from server
                }
            }
        }
        xmlhttp.open("GET","getCompany.php",true);
        xmlhttp.send();
    }

    function getTenant(id){
        if (window.XMLHttpRequest) {
            // code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp=new XMLHttpRequest();
        } else { // code for IE6, IE5
            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
        }
        xmlhttp.onreadystatechange=function y() {
            if (xmlhttp.readyState==4 && xmlhttp.status==200) {
                result = xmlhttp.responseText;
                result = result.split(",");
                //fill the form with old information
                document.getElementById("fname").value = result[0];
                document.getElementById("lname").value = result[1];
                document.getElementById("company").selectedIndex = result[2];
                document.getElementById("phone").value = result[3];
                document.getElementById("email").value = result[4];
                document.getElementById("crm").value = result[5];
            }
        }
        xmlhttp.open("GET","getTenant.php?p=" + id,true);
        xmlhttp.send();
    }
</script>

Upvotes: 2

Diptendu
Diptendu

Reputation: 2158

It is happening because of a race condition between the two XHR calls made from getCompany and getTenant methods. Even though you are making the getTenant call 200ms after making the first XHR call there is no guarantee that the getComapny XHR call will finish first. When that happens the follwoing line of code

document.getElementById("company").innerHTML = xmlhttp.responseText;

removes all the options from the menu and also resets the selected index. To circumvent this issue do not make getTenant(id); call from init method. Instead make it from the success handler of the getCompany XHR call.

            xmlhttp.onreadystatechange=function x() {
                if (xmlhttp.readyState==4 && xmlhttp.status==200) {
                    document.getElementById("company").innerHTML = xmlhttp.responseText;
                    **getTenant(id);**
                }
            }

Upvotes: 0

Related Questions