Search code examples
javascripttypescriptxmlhttprequest

XMLHttpRequest Typescript conflict with 'this'


I have an issue using XMLHttpRequest with typescript, here is a typescript class:

class Myclass {
 constructor() {
   this.init();
 }

 private init() {
  const req = new XMLHttpRequest();
  req.onreadystatechange = ( event: Event ): any => {
   if (this.readyState === XMLHttpRequest.DONE) {
    if (this.status === 200) {
      this.render(this.responseText)
    }
   }
  };

  req.open('GET', '/api/test', true);
  req.send(null);
 };

private render( data:any ) {
  console.log(`use ${data}`)
 }
}

in this case 'this' will refer to the typescript class Myclass and using a javascript function 'this' will refers to the request and i will not be able to call my class method render().

how can i call my render() method and still have access to the response ?


Solution

  • You can already access the XMLHttpRequest using the req variable.

    If you prefer a more clean way, you can bind the request to your callback function lite so:

    req.onreadystatechange = (function ( request: XMLHttpRequest, event: Event ): any {
        if (request.readyState === XMLHttpRequest.DONE) {
            if (request.status === 200) {
                this.render(request.responseText)
            }
        }
    }).bind(this, req);
    

    or use the other way round:

    req.onreadystatechange = (function ( myClassObject: MyClass, event: Event ): any {
        if (this.readyState === XMLHttpRequest.DONE) {
            if (this.status === 200) {
                myClassObject.render(this.responseText)
            }
        }
    }).bind(req, this);
    

    With the bind function you can assign a fixed this object to a function as well as parts or all of its parameters.

    https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Function/bind