-1

Case: So I am receiving JSON data from the back end and I want to display that data in a table. I am creating a string named tableOutputString and while iterating through JSON I am concatenating the response into the tableOutputString. At the end I am using innerHTML to display the table.

Note: Look at the code between "Starts here" and "Ends here".

Problem: Inside the function I have nested AJAX. In the inner AJAX I am trying to concatenate tableOutputString but it is not happening. I think there is some scope issue. I can see the tableOutputString updated when I am inside AJAX scope, but once I come out of the outer AJAX, my string becomes the same as I had before I entered in the AJAX. Please help me on this.

function displaytable(response) {

    //  Variable to check the length of the JSON abject
    var lengthOfJSON = Object.keys(response).length;
    var tableOutputString = "";
    var Exam_id = "";

    //  creating the body part of the table
    tableOutputString = tableOutputString + '<tbody>';
    for (var i = 0; i < lengthOfJSON; i++) {
        tableOutputString = tableOutputString + '<td>' + (i + 1) + '</td>';

        for (var key in response[i]) {
            if (key == "exam_name") {
                Exam_id = response[i]["exam_id"];
                tableOutputString = tableOutputString + '<td>' + '<a href="#"' + "onclick=getExam(" + Exam_id + ")>" + response[i][key] + '</a>' + '</td>';
            } else {
                tableOutputString = tableOutputString + '<td>' + response[i][key] + '</td>';
            }
        }


        /* Starts Here */

        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function () {
            if (this.readyState == 4 && this.status == 200) {
                var response = JSON.parse(this.responseText);

                if (response["taken"] == "true") {
                    var xhttp = new XMLHttpRequest();
                    xhttp.onreadystatechange = function () {
                        if (this.readyState == 4 && this.status == 200) {
                            var response = JSON.parse(this.responseText);
                            if (response["graded"] == "true") {
                                tableOutputString = tableOutputString + '<td>' + "graded" + '</td>';   // trying to concatenate 
                            }
                            else {
                                tableOutputString = tableOutputString + '<td>' + "Not graded" + '</td>';   // trying to concatenate 
                            }
                        }
                    };
                    xhttp.open("POST", "getWasUserExamGraded.php?id=" + Exam_id, true);
                    xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
                    xhttp.send();
                }
                else {
                    tableOutputString = tableOutputString + '<td>' + "Not taken" + '</td>';   // trying to concatenate 
                }
            }
        };
        /* Ends Here */


        xhttp.open("POST", "getDidTakeExam.php?id=" + Exam_id, true);
        xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhttp.send();
        tableOutputString = tableOutputString + '</tbody>';    //tableOutputString is not updated inside AJAX 

        document.getElementById("responstable").innerHTML = tableOutputString;
    }
}
Kenji Mukai
  • 599
  • 4
  • 8
  • You're not creating any `` elements. `` should be inside of `` tag. `` is a row container, and each `` represents a cell for that row – mhodges Oct 19 '17 at 22:26
  • Thanks @mhodges. This is not a problem for me. The scope is a causing me a problem. Whatever I am updating inside the AJAX is not getting updated. Right now, my table is complete except one column, and it is because of this. However, thanks for the reply. – Rohan Mavani Oct 19 '17 at 22:33
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – CBroe Oct 19 '17 at 23:37

1 Answers1

0

I think the problem is the time when you update the table, have you tried update your table inside of onreadystatechange

var cellText;
if (response["graded"] == "true") {
    cellText = '<td id="gradedCell">' + "graded" + '</td>';
} else {
    cellText = '<td id="gradedCell">' + "Not graded" + '</td>';
}
document.getElementById("gradedCell").innerHTML = cellText ;
  • 1
    That's a good start, but all of the OP's code is in a big `for` loop, which means the ajax calls are going to be hit several times, each time overwriting the innerHTML. – Mark Oct 19 '17 at 23:25