2

I have a function sending a simple AJAX request to my server. The browser's javascript code looks like this:

function testRequest() {

    var xhr = new XMLHttpRequest();
    xhr.onload = () => {

        console.log("RESPONSE RECIEVED");
        console.log(this); // 'this' should be a XMLHttpRequest object
        console.log(this.status);
        console.log(this.responseText);
    };

    xhr.open('POST', `http://server_ip/test`, true);
    xhr.send();
}

The server code looks like this (Express.js):

app.post("/test", (req, res) => { 

    res.setHeader("Access-Control-Allow-Origin", "*");
    res.status(200).send("testing");
});

When the function is called, the response I'm getting on the browser console is this:

RESPONSE RECIEVED
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}

undefined

rather than the expected:

RESPONSE RECIEVED
XMLHttpRequest {…}
200
"testing"

In other words, the server response is being recieved by the browser, however the object being passed into the onload function (this) appears to be some 'Window' object rather than an XMLHttpRequest object. As a result, there is no status or responseText variable.

When inspecting the request in the browser, the body of the response is indeeed the expected 'testing'.

Legatro
  • 3,692
  • 4
  • 15
  • 21

1 Answers1

3

This is because you are using an arrow function () =>, in such functions the this is lexically captured and does not change with the context. In your case the this is pointing to the window context as that is the enclosing lexical scope i.e. where it was declared.

You need to change it to a normal function to make this point to the xhr object:

xhr.onload = function(){
      console.log("RESPONSE RECIEVED");
      console.log(this); // 'this' should be a XMLHttpRequest object
      console.log(this.status);
      console.log(this.responseText);
};

From the MDN docs:

An arrow function does not have its own this. The this value of the enclosing lexical scope is used; arrow functions follow the normal variable lookup rules. So while searching for this which is not present in current scope, an arrow function ends up finding the this from its enclosing scope.

Fullstack Guy
  • 16,368
  • 3
  • 29
  • 44