XMLHttpRequest properties (onReadyStateChange, readyState, responseText, responseXML)

Four properties run every AJAX call: onreadystatechange is your doorbell, readyState counts the journey 0 to 4, responseText and responseXML carry the answer, and status says whether it is good news.

11 min read · 10 cards · 2 checks

Read in: English · हिन्दी · ગુજરાતી


Theory

How do you wait for something asynchronous?

Last lesson's runner departed with send(), and your code moved on immediately: that was the point. But then... how does your script ever learn the answer ARRIVED?

You cannot loop and check (that would freeze the page: the exact disease we are curing). The runner must ring a bell when there is news.

The XMLHttpRequest object is built around that bell, a progress counter, and 2 pockets for the answer: 4 properties that between them run every AJAX call ever made.

Theory

The bell and the counter

onreadystatechange holds the function you want called whenever the request's state changes: assign it BEFORE sending. It is not called once; it fires at every stage of the journey.

readyState is the stage number, 0 through 4. The request walks up the scale as it progresses, and each step rings your handler. The one you almost always await is 4: finished, response ready.

Bell plus counter is the asynchronous answer to "how do I wait?": you do not wait: you get called.

At a glance

readyState 0 to 4 (the exam table: learn it verbatim)

ValueStateMeaning
0Request not initializedObject created; open() not yet called
1Server connection establishedopen() has been called
2Request receivedsend() called; response headers arrived
3Processing requestResponse body downloading
4Request finished, response readyThe answer is fully in hand

Theory

The two pockets, and the verdict

When readyState hits 4, the answer sits in one of 2 properties:

  • responseText: the response as a plain string: THE pocket for JSON (JSON.parse(xhr.responseText)) and any text
  • responseXML: the response as a parsed XML document, ready for DOM-style access (getElementsByTagName): meaningful only when the server actually sent XML

And one more property renders the verdict: status, the HTTP code: 200 means OK; 404 means not found. Finished (readyState 4) and successful (status 200) are different facts: check both.

Practical

Watching the journey, state by state (complete page)

<!DOCTYPE html>
<html>
<head>
  <script>
    function fetchSeats() {
      var xhr = new XMLHttpRequest();          // readyState is 0 here
      xhr.onreadystatechange = function() {    // the bell: fires per stage
        document.getElementById("log").innerHTML +=
          "readyState: " + xhr.readyState + "<br>";

        if (xhr.readyState == 4 && xhr.status == 200) {
          var data = JSON.parse(xhr.responseText);   // the string pocket
          document.getElementById("seats").innerHTML = data.seats;
        }
        if (xhr.readyState == 4 && xhr.status == 404) {
          document.getElementById("seats").innerHTML = "file missing!";
        }
      };
      xhr.open("GET", "seats.json", true);     // readyState becomes 1
      xhr.send();                              // then 2, 3, 4 as it runs
    }
  </script>
</head>
<body>
  <p>Seats: <span id="seats">?</span></p>
  <div id="log"></div>
  <button onclick="fetchSeats()">Fetch</button>
</body>
</html>

This example runs in Gri-Learn on the web, where you can edit it and see the output.

Quiz

An AJAX handler updates the page inside if (xhr.readyState == 4) with no other condition. The server replies 404 because seats.json was renamed. What does the user see?

  1. Nothing: readyState never reaches 4 on an error
  2. The page updates with the 404 error page's text poured in as if it were data
  3. The browser retries the request automatically
  4. JSON.parse waits until a correct file appears
Show the answer

The page updates with the 404 error page's text poured in as if it were data

readyState measures COMPLETION, not success: a 404 response is a completed request, so state 4 arrives carrying the server's error page as responseText, and unguarded code parses or displays garbage (JSON.parse throwing on '<html>...' is this bug's loudest symptom). That is why the canonical guard is readyState == 4 AND status == 200: finished AND successful. Option A is the exact misbelief being tested. Options C and D describe mercies that do not exist: no retries, no waiting: the response you got is the response you handle.

Think first

How many times does the bell ring?

Click Fetch in the listing and read its log div. Before tapping: how many lines appear for one successful request, showing which numbers, and why does the handler need an if at all?

Show the answer

Typically 4 lines: 1, 2, 3, 4: onreadystatechange fires at every transition after open() (state 1 as open executes, then 2, 3 and 4 as the response arrives; 0 was the state at creation, before any change fires the bell). The if exists precisely because of this multiplicity: your update-the-page code must run at stage 4 ONLY: without the guard it would attempt to read an answer that has not arrived, 3 times per request. Bell rings often; you act once.

Watch out

Property mix-ups that cost marks

responseText vs responseXML: text is a string for JSON.parse and display; responseXML is a pre-parsed XML DOCUMENT: calling JSON.parse on responseXML, or getElementsByTagName on responseText, are both category errors.

Assigning the handler AFTER send(): on a fast (cached) response, early states can fire before your bell is installed: always wire onreadystatechange before send.

Writing the table loosely: "2 means request received, 3 means processing" must not swap: exams grade the exact wording.

Theory

The pattern to memorise as one unit

Every raw AJAX call you will ever write is the same 5-line skeleton: create the object, assign onreadystatechange, guard with 4-and-200, open, send. Learn today's listing until you can reproduce it with your eyes closed: exam AJAX questions are this skeleton with the URL changed. Two verbs remain unexplained in it: what open() and send() precisely do, plus the third method for headers: next lesson finishes the object.

Summary

Key takeaways

  • onreadystatechange holds your handler; it fires at EVERY state change, so guard inside it.
  • readyState: 0 not initialized, 1 connection established, 2 request received, 3 processing, 4 finished and ready: learn the table verbatim.
  • responseText = the answer as a string (JSON's pocket); responseXML = a parsed XML document.
  • status is the HTTP verdict: 200 OK, 404 not found.
  • The canonical guard: if (readyState == 4 && status == 200): finished AND successful.
  • Wire the handler before send(); act only at stage 4.
  • Memory hook: the bell rings 4 times; open the door on the fourth, and check who it is.

Study this properly

This page is the lesson to read. In Gri-Learn the same topic is a graded deck: the self-checks are scored and your weak topics are tracked. Free to start.

Start this topic

Already have an account? Sign in

More from AJAX (Asynchronous JavaScript and XML)

Gri-Learn · syllabus-mapped B.C.A. lessons in English, Hindi and Gujarati

XMLHttpRequest properties (onReadyStateChange, readyState, responseText, responseXML) · Web Designing-2 (option A) · Gri-Learn