23

I have the following in a module file:

module.exports = {
    myfunc: myfunc
};

var myfunc = function(callback){    
        callback(err,reply);    
};

In an other file I got the reference to that module

var mymodule = require('./modules/mymodule');
mymodule.myfunc(function(err, reply){ ... });

When I call the mymodule.myfunc() I get an error saying "property 'myfunc' is not a function". This happens only with exported functions. The same module exports some 'string' fields and these are working just fine.

3 Answers 3

37

When you assign module.exports, the myfunc function is still undefined. Try to assign it after declaring it:

var myfunc = function(callback){    
    callback(err,reply);    
};

module.exports = {
    myfunc: myfunc
};
3
  • 11
    well, that was embarrassing.. Thanks.
    – Idan
    Commented Jan 13, 2014 at 14:14
  • 1
    I've defined my function with const myfunc ... and then tried to export it at the end and I still get a similar error... can I not export a function with const access modifier?
    – ahong
    Commented Jan 10, 2019 at 8:59
  • 1
    Edit: that was embarrassing. Apparently I used exports = {} directly and that messed everything up: adrianmejia.com/blog/2016/08/12/…
    – ahong
    Commented Jan 10, 2019 at 9:04
11

To preserve your original ordering of module.exports at the top of your file, change your var myfunc initialization to a function myfunc declaration so that the latter is hoisted.

module.exports = {
    myfunc: myfunc
};

function myfunc(callback){    
    callback(err,reply);    
};

Declarations are hoisted, but initializations are not, which is why your original example did not work. w3schools has a practical description of JavaScript Hoisting.

2
  • Am a beginner in these, can i know why ` myfunc: myfunc` is used means what does that mean
    – Amrit Bera
    Commented Apr 18, 2022 at 1:56
  • @AmritBera module.exports is assigned to an object. In JS, an object is constructed using key-value pairs surrounded by curly braces. For instance, let obj = { foo: 'bar' }. This answer shows an object with a key named myfunc associated to a value that is a function also named myfunc.
    – testing_22
    Commented Oct 27, 2023 at 23:28
0

Another scenario where i found this annoying issue was if explicitly imported only the function that my consumer needs

Say for example your exported modules looks like below

module.exports = {
    func1 : async function func1(){}
    func2 : async function func2(){
        await this.func1(); // causes error : func1 is not a function
    }
}

Now your consumer of above module looks like below:

const { func2 } = require('../theExportedModules'); 
//above only imports func2 but not its dependents and is not initialized    
await func2(); //func2 called

Now func2() gets called from your consumer but func2() will not be able to call the func1() because it finds that func1() is not a function. Code breaks!

solution import entire modules:

const theExportedModules = require('../theExportedModules'); 

we could also just import func1 as well but then it would be an unused variable and we would get a warning for that.

Not the answer you're looking for? Browse other questions tagged or ask your own question.