Slim
Slim

Reputation: 6197

Class.method is not a function using ES6 classes

I create a class and I want to use the method in routes in my node.js application. A simple snippet code describe a smilar issue that I faced in my real app.

myClass.js:

class MyClass {
    static async sayHi(name) {
        setTimeout(() => {
            return `Hello ${name}`
        }, 3000)
    }
}

module.exports = new MyClass()

index.js:

const MyClass = require('./myClass');
console.log(MyClass.sayHi)

I got this error:

undefined

Trying:

console.log(MyClass.sayHi('Hello'))

returns:

MyClass.sayHi is not a function

Upvotes: 2

Views: 5925

Answers (4)

Murtaza Hussain
Murtaza Hussain

Reputation: 4315

Change line from instance to Class itself, as Static methods are the methods that can be called without creating an instance of class.

module.exports = MyClass;

and change the require to the file name

 const MyClass = require('./myClass.js');

Upvotes: 1

flashyhawk
flashyhawk

Reputation: 11

@Murtaza Hussain is right.

As the method is static. you can just export the class instead creating an instance.

module.exports = MyClass;

Upvotes: 1

Tim VN
Tim VN

Reputation: 1193

You are exporting an instance of MyClass. Static methods are not called on instances of the class, but rather on the class itself.

If you export MyClass like so: module.exports = MyClass, your second approach should work.

edit:

As @T.J. Crowder pointed out. If the class is in a file called MyClass.js, import from there instead of index.

Upvotes: 3

CertainPerformance
CertainPerformance

Reputation: 371193

You're exporting an instance of the class - when importing, you have an instance, not the actual class. Calling the imported object MyClass is confusing - maybe call it myClassInstance instead, which would make it clear what the problem is.

If you have an instance, and want to call a static method on the class, reference the .constructor property.

If you want to return something asynchronously, best to use a Promise, and then call .then on the sayHi call to consume the Promise:

class MyClass {
  static sayHi(name) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(`Hello ${name}`);
      }, 1000);
    });
  }
}

const myClassInstance = new MyClass();
// module.exports = myClassInstance;

// index.js:

// const myClassInstance = require('./index');
myClassInstance.constructor.sayHi('foo')
  .then(console.log);

No need for the static method to be async, since you're already returning a Promise explicitly.

Upvotes: 6

Related Questions