3

Calling javascript static method using this.constructor gives TypeError. Below is the code,

parent.js,

module.exports = class parent {
        persist(data) {
            data = this.constructor._sanitizeData(data);
            // remaining code using the sanitized data
        }

        static _sanitizeData(data) {
            for (let prop in data) {
                if (typeof data[prop] === 'object') {// dive deeper in

                    this.constructor._sanitizeData(data[prop]);
                } else if(data[prop] === '') {
                    delete data[prop];
                }
            }
            return data;
        }
    }

child.js,

const parent = require('parent');

module.exports = class child extends parent {
}

index.js,

const child = require('child');

let childObj = new child();
childObj.persist({a:1, b:2});

Above code gives the following error TypeError: this.constructor._sanitizeData is not a function

I am using NodeJs 8.10 in aws lambda.

Rohith Mohan
  • 187
  • 1
  • 14
  • Why are you using a static method and not just a normal class method? – CertainPerformance Apr 17 '18 at 03:34
  • @CertainPerformance so that I need not create instance to call the function – Rohith Mohan Apr 17 '18 at 03:37
  • 2
    Runs fine for me: https://jsfiddle.net/pcq9s226/1/ and you don't have to instantiate something to reference the function: `parent.prototype.persist` for example – CertainPerformance Apr 17 '18 at 03:40
  • I am running it in aws lambda. Not sure if it is any different. – Rohith Mohan Apr 17 '18 at 03:40
  • @JasonGoemaat thanks for pointing that out. Updated the code. – Rohith Mohan Apr 17 '18 at 03:43
  • @CertainPerformance I can make it a normal class method and use parent.prototype.persist for accessing it as you mentioned. Thanks for your help. However, I still have no clue as to why this is giving typeError in lambda. – Rohith Mohan Apr 17 '18 at 03:45
  • @JasonGoemaat I only get error when run in aws lambda. The two classes are in two separate files. That is the only difference. I might update the code with the exports. – Rohith Mohan Apr 17 '18 at 03:47
  • This works for me in AWS lambda with Nodejs 8.10. I have both classes in the same file. Probably be a problem with export/import? – Kavindra Apr 17 '18 at 03:51
  • If you take out the call to `_sanitizeData` does it work? What if you call `parent._sanitizeData`? – Jason Goemaat Apr 17 '18 at 03:52
  • It works, if I use parent._sanitizeData(data) instead of this.constructor._sanitizeData(data) , but using parent._sanitizeData(data) won't help if I'm overriding the function in the child. – Rohith Mohan Apr 17 '18 at 03:53
  • So you want a method on the parent to possibly use a static method on a child class? Unusual, if calling it from an instance there'd be no need, and if not from an instance then you would need to specify which class you wanted... So does it work fine if you make it a non-static method? – Jason Goemaat Apr 17 '18 at 04:03
  • @JasonGoemaat It does work when it is made non-static. The whole point of making it static was that I can use the function even without creating an instance. Also, I didn't understand why overriding a static function is unusual. – Rohith Mohan Apr 17 '18 at 04:08
  • 1
    Most languages don't let you do that (C# and Java I know) because calling a static function doesn't have an instance and it doesn't make sense to be overridden because it is called using the class. See [here](https://stackoverflow.com/questions/2223386/why-doesnt-java-allow-overriding-of-static-methods). You want to change the functionality of a method that is not overridden based on the constructor used to create the object. Because it is a non-static method, why not just override that method to use different logic if you need to rather than use the inherited method with different logic? – Jason Goemaat Apr 17 '18 at 06:26
  • What line gives you the TypeError? Is there any other information? Can you post the whole error message? TypeError can be caused when you try to execute a method that doesn't exist on the object... – Jason Goemaat Apr 17 '18 at 06:37
  • @JasonGoemaat That is a good piece of information. I have a PHP background and it allows static methods to be overridden. To your question of what line gives the error, both the lines that has `this.constructor._sanitizeData(data)` gives the TypeError. I doubt if it has something to do with export/import as @Kavindra suggested – Rohith Mohan Apr 18 '18 at 00:00
  • From what you've given I'm guessing that AWS does something special that doesn't put static methods on the constructor, I don't know what. Your best bet is to probably override persist if you change the static method functionality in a subclass and put the different logic there... – Jason Goemaat Apr 19 '18 at 07:21
  • @RohithMohan I am having the same issue. Did you happen to find any solution? Thanks. – LeOn - Han Li May 01 '18 at 12:18
  • Unfortunately, I didn't spend more time fixing it rather made the method non static. However, it would be nice if you can share what the cause is when you find it. – Rohith Mohan May 02 '18 at 21:51

0 Answers0