Search code examples
javascriptangularxmlhttprequestecmascript-5

JavaScript Prototype Inheritance scope inside ES5 Class


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);
            };
        }
    }