Jamie Fearon
Jamie Fearon

Reputation: 2634

Ajax is correctly returning and displaying data but error message is being activated

I'm performing AJAX using the following code:

function main() {

    // get the name fields
    var name1 = document.getElementById("name1").value;
    var name2 = document.getElementById("name2").value;

    // Encode the user's input as query parameters in a URL
    var url = "response.php" +
        "?name1=" + encodeURIComponent(name1) +
        "&name2=" + encodeURIComponent(name2);

    // Fetch the contents of that URL using the XMLHttpRequest object
    var req = createXMLHttpRequestObject();
    req.open("GET", url);

    req.onreadystatechange = function () {
        if (req.readyState == 4 && req.status == 200) {
            try {
                // If we get here, we got a complete valid HTTP response
                var response = req.responseText; // HTTP response as a string
                var text = JSON.parse(response); // Parse it to a JS array

                // Convert the array of text objects to a string of HTML
                var list = "";
                for (var i = 0; i < text.length; i++) {
                    list += "<li><p>" + text[i].reply + " " + text[i].name + "</p>";
                }

                // Display the HTML in the element from above.
                var ad = document.getElementById("responseText");
                ad.innerHTML = "<ul>" + list + "</ul>";
            } catch (e) {
                // display error message
                alert("Error reading the response: " + e.toString());
            }
        } else {
            // display status message
            alert("There was a problem retrieving the data:\n" + req.statusText);
        }
    }

    req.send(null);

}


// creates an XMLHttpRequest instance
function createXMLHttpRequestObject() {
    // xmlHttp will store the reference to the XMLHttpRequest object
    var xmlHttp;
    // try to instantiate the native XMLHttpRequest object
    try {
        // create an XMLHttpRequest object
        xmlHttp = new XMLHttpRequest();
    } catch (e) {
        // assume IE6 or older
        try {
            xmlHttp = new ActiveXObject("Microsoft.XMLHttp");
        } catch (e) {}
    }
    // return the created object or display an error message
    if (!xmlHttp) alert("Error creating the XMLHttpRequest object.");
    else return xmlHttp;
}

This works exactly as planned, the code within the try block is executed perfectly. But the alert "There was a problem retrieving the data: is also activated, with req.statusText displaying "OK".

How can this be possible? How can the code within the if statement activate perfectly but at the same time the else block is activated?

I'm stumped, any ideas?

The servor code is simply:

<?php

if( $_GET["name1"] || $_GET["name2"] ) {
    $data = array(
     array('name' => $_GET["name1"], 'reply' => 'hello'),
     array('name' => $_GET["name2"], 'reply' => 'bye'),
    );
    echo json_encode($data);
}

?>

And the HTML:

<input id="name1">
<input id="name2">
<div id="responseText"></div>
<button onclick="main();">Do Ajax!</button>

Upvotes: 2

Views: 122

Answers (1)

Ishmael
Ishmael

Reputation: 32560

Your conditional is probably being activated when req.readyState == 3 (content has begun to load). The onreadystatechange method may be triggered multiple times on the same request. You only care about what happens when it's 4, so refactor your method to only test when that is true:

var req = createXMLHttpRequestObject();
req.open("GET", url);
req.onreadystatechange = function() {
    if (req.readyState == 4) {
        if (req.status == 200) {
            try {
                // If we get here, we got a complete valid HTTP response
                var response = req.responseText; // HTTP response as a string
                var text = JSON.parse(response); // Parse it to a JS array

                // Convert the array of text objects to a string of HTML
                var list = "";
                for (var i = 0; i < text.length; i++) {
                    list += "<li><p>" + text[i].reply + " " + text[i].name + "</p>";
                }

                // Display the HTML in the element from above.
                var ad = document.getElementById("responseText");
                ad.innerHTML = "<ul>" + list + "</ul>";
            } catch(e) {
                // display error message
                alert("Error reading the response: " + e.toString());
            }
        } else {
            // display status message
            alert("There was a problem retrieving the data:\n" + req.statusText);
        }
    }
};
req.send(null);

Upvotes: 2

Related Questions