onreadystatechange() missing on XMLHttpRequest objects

10,541

Solution 1

onreadystatechange does exist...that's why it's null. If it didn't exist, it would be undefined. It all depends on whether it's been set already. It's clearly already a property because it's null...if it weren't, it would be undefined...or at least "onreadystatechange" in this would be false.

Here's an example:

var a = new XMLHttpRequest();
a.onreadystatechange = function () {
};
a.send();

Your console will log a function.

If you had:

var b = new XMLHttpRequest();
b.send();

Your console would log null.

Here's a demo of this happening: http://jsfiddle.net/3XKx7/

(I clearly left other steps out for sending an AJAX request, it was just for explanation)

I'm not trying to imply there's a relation between null and undefined - I'm just saying that when creating a new XMLHttpRequest, the onreadystatechange will be set to null internally. Whether you set it to a function or not is up to you.

UPDATE:

The normal way for creating/sending an XHR is this order:

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {    // This and `open` could be flip-flopped
    // whatever
};
xhr.open("POST", url, true);
xhr.send("data=data");

I was always told/shown to create the new XMLHttpRequest, then whatever order of setting onreadystatechange and calling open, but only after both of those should I call send.

So, if that were always done, onreadystatechange (if actually set) would not be null and would be a function.

Since you mentioned you were using jQuery, I decided to test with overriding the send method like you want, and making a jQuery $.ajax call (not sending a XMLHttpRequest manually). Here's my testing - http://jsfiddle.net/3XKx7/1/

It doesn't make sense why onreadystatechange would be null, because jQuery has to be binding to that event in order to know when the request completes and its state. So I decided to look at the jQuery source code. And what I found was that the order they call things is:

xhr.open()
xhr.send()
xhr.onreadystatechange = function () {

};

Which means that when you're overriding the send method, onreadystatechange is null since jQuery doesn't set it before calling send. I don't know their reasoning for it...it might be to prevent things like what you're doing...but I never heard of or saw this convention being used.

So the reason you're getting its value as null is because jQuery sets onreadystatechange after calling send. Meaning that when you override send and try to access the onreadystatechange property, it isn't set yet.

Hopefully this is an example that can help you understand: http://jsfiddle.net/dMP6q/16/

Solution 2

You're supposed to set it yourself, this function will be called when the state change. It's just like the other event handlers, like document.onload, yourelement.onclick, etc.

Classically you do

    var httpRequest = new XMLHttpRequest();
    httpRequest.onreadystatechange = function() {
        if (httpRequest.readyState === 4) {
              if (httpRequest.status === 200) {
                  // use httpRequest.responseText
              }
        }
    };
    httpRequest.open('GET', url);
    httpRequest.send();
Share:
10,541
Johan
Author by

Johan

Updated on June 27, 2022

Comments

  • Johan
    Johan almost 2 years
    (function (send) {
    
         XMLHttpRequest.prototype.send = function () {
    
             console.log(this.onreadystatechange); //null
             send.apply(this, arguments);
         };
    
    })(XMLHttpRequest.prototype.send);
    

    Why is this.onreadystatechange null? According to this it should exist and be of type function.