Search code examples
javascriptajaxcallbackxmlhttprequestfunction-binding

XMLHttpRequest and Binding a Callback not working


I have a simple get function using XMLHttpRequest which accepts a callback parameter. The plan is to invoke the callback on the onload event handler.

Here is a simplified version:

get(url,doit);

function doit(data) {
    alert(data)
}
function post(url,callback) {
    var xhr=new XMLHttpRequest();
    xhr.onload=function() {                     //  Version 1
        callback(xhr.response)
    }
    xhr.onload=callback.bind(xhr,xhr.response); //  Version 2
    xhr.open('get',url,true);
    xhr.send(data);
}

The callback function has one parameter, data which is supposed to be the response from the Ajax Call.

I have 2 versions of invoking the callback:

  1. Version 1 simply calls the callback inside the event handler function.
  2. Version 2 uses bind to do the same; this is set to the xhr object, while the xhr.response is sent as the argument.

When I use Version 1, everything works as expected. When I use Version 2, the data parameter is empty.

I thought I knew XMLHttpRequest and .bind() reasonably well, but I cannot work out why the second version is empty. What is (not) happening here?

Comment

Thanks to the answers, I think I have it.

.bind() is executed immediately with the current value of xhr.responseText, which, at this stage, is nothing.

It appears that the first Version is preferable if I need to respond with a future value.

Thanks all.


Solution

  • It's because callback.bind will be executed immediately. And at the time it is executed, xhr.responseText is obviously not available since the request has not been completed yet. You can try this to see the result.

    function doit(data) {
        alert(data, this.responseText);
    }