[Fixed] JavaScript Prototype Inheritance scope inside ES5 Class

Issue

I am trying to write XMLHttpRequest interceptor for Angular, but I can’t simply use HttpInterceptor because I need to intercept third party library which uses XMLHttpRequest API.

Overall bellow solution works, but I’m messing up with defining a scope of prototype inside classes. Plus if I use arrow functions, its just not coming along.

export class Interceptor {
    constructor(private config) {
        const XMLHttpRequestOpen = window.XMLHttpRequest.prototype.open;

        window.XMLHttpRequest.prototype.open = function (method, url) {
            if (url === this.config.url) { // this.config is out of scope of class
                this.onreadystatechange = function() {
                    this.setRequestHeader('Authorization', 'Bearer ...');
                };
            }
            return XMLHttpRequestOpen.apply(this, arguments);
        };
    }
}

Any neat solutions are welcomed.

Solution

Store the value you want to access later in a variable that isn’t a property of this, so that it won’t be lost to the rebinding.

export class Interceptor {
    constructor(private config) {
        const XMLHttpRequestOpen = window.XMLHttpRequest.prototype.open;
        const configUrl = this.config.url;

        window.XMLHttpRequest.prototype.open = function (method, url) {
            if (url === configUrl) {
                this.onreadystatechange = function() {
                    this.setRequestHeader('Authorization', 'Bearer ...');
                };
            }
            return XMLHttpRequestOpen.apply(this, arguments);
        };
    }
}

Leave a Reply

(*) Required, Your email will not be published