TypeScript And Serverless: `this` Undefined When Calling Private Methods from Public Methods

I am trying to build an AWS Serverless(https://serverless.com/) function in TypeScript.

Specifically, I am defining an abstract class with a single public method that calls some private methods.

Here is my simplified TypeScript class:

export abstract class AbstractPayloadProcessor {

    private preHandlePayload(payload) {
        console.log('arrived in prehandle method')
    }

    private postHandlePayload(payload) {
        console.log('arrived in posthandle method')
    }

    protected handleException(error) {
        console.log('Exception has occurred:', error)
    }

    public processPayload(event) {

        // this is the problematic line
        this.preHandlePayload(event.payload)
        .
        .
        .
    }
}

I use webpack transpile this into ES5, which produces the following JavaScript:

var AbstractPayloadProcessor = /** @class */ (function () {
    AbstractPayloadProcessor.prototype.preHandlePayload = function (payload) {
        console.log('arrived in prehandle method');
    };
    AbstractPayloadProcessor.prototype.postHandlePayload = function (payload) {
        console.log('arrived in posthandle method');
    };
    AbstractPayloadProcessor.prototype.handleException = function (error) {
        console.log('Exception has occurred:', error);
    };
    AbstractPayloadProcessor.prototype.processPayload = function (event) {
        // this line throws the exception
        this.preHandlePayload(event.payload);
        .
        .
        .
}());

The exact exception is:

TypeError: Cannot read property 'preHandlePayload' of undefined

So far, I have tried setting the webpack config to use ES6 and have tried to use arrow functions to declare the functions in typescript. Both produce the same exception.

The processPayload function is being called somewhere within the Serverless framework, but I do not know the implementation details. If anyone has experience with the framework and can shed some light on that, I would appreciate it.

Thanks for reading.

Answers:

Answer

Wild guess

I guess that what you're doing is using someObject.processPayload and passing it as a callback to some function, or saving it somewhere as an event handler. This function in turn calls this.preHandlePayload() but it can't because not having been called properly it has its this undefined.

More info

There are few possible things that can cause this to be undefined inside of a method, and it is not important if it is private or public - because as you can see all of them end up being public after the transpilation.

One possible way is for example inside method1 if you call method2() instead of this.method2() then you will have this undefined in method2.

Another common mistake is saving a method as an event handler or using it as a callback, for example:

x.onSomething = object.method;

or

functionThatTakesCallback(object.method);

For those cases to work you either need to pass an anonymous function like:

x.onSomething = (...args) => object.method(...args);

or binding the method to that object:

x.onSomething = object.method.bind(object);

Of course, it's hard to tell what's really the problem in your case because you didn't how us how you actually call your methods and this is the calling not the definition of methods that usually puts undefined in this.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.