Call a "local" function within module.exports from another function in module.exports?
node.jsExpressnode.js Problem Overview
How do you call a function from within another function in a module.exports
declaration?
app.js
var bla = require('./bla.js');
console.log(bla.bar());
bla.js
module.exports = {
foo: function (req, res, next) {
return ('foo');
},
bar: function(req, res, next) {
this.foo();
}
}
I'm trying to access the function foo
from within the function bar
, and I'm getting:
> TypeError: Object # has no method 'foo'
If I change this.foo()
to just foo()
I get:
> ReferenceError: foo is not defined
node.js Solutions
Solution 1 - node.js
Change this.foo()
to module.exports.foo()
Solution 2 - node.js
You could declare your functions outside of the module.exports
block.
var foo = function (req, res, next) {
return ('foo');
}
var bar = function (req, res, next) {
return foo();
}
Then:
module.exports = {
foo: foo,
bar: bar
}
Solution 3 - node.js
You can also do this to make it more concise and readable. This is what I've seen done in several of the well written open sourced modules:
var self = module.exports = {
foo: function (req, res, next) {
return ('foo');
},
bar: function(req, res, next) {
self.foo();
}
}
Solution 4 - node.js
You can also save a reference to module's global scope outside the (module.)exports.somemodule definition:
var _this = this;
exports.somefunction = function() {
console.log('hello');
}
exports.someotherfunction = function() {
_this.somefunction();
}
Solution 5 - node.js
Another option, and closer to the original style of the OP, is to put the object you want to export into a variable and reference that variable to make calls to other methods in the object. You can then export that variable and you're good to go.
var self = {
foo: function (req, res, next) {
return ('foo');
},
bar: function (req, res, next) {
return self.foo();
}
};
module.exports = self;
Solution 6 - node.js
const Service = {
foo: (a, b) => a + b,
bar: (a, b) => Service.foo(a, b) * b
}
module.exports = Service
Solution 7 - node.js
Starting with Node.js version 13 you can take advantage of ES6 Modules.
export function foo() {
return 'foo';
}
export function bar() {
return foo();
}
Following the Class approach:
class MyClass {
foo() {
return 'foo';
}
bar() {
return this.foo();
}
}
module.exports = new MyClass();
This will instantiate the class only once, due to Node's module caching:
https://nodejs.org/api/modules.html#modules_caching
Solution 8 - node.js
To fix your issue, i have made few changes in bla.js and it is working,
var foo= function (req, res, next) {
console.log('inside foo');
return ("foo");
}
var bar= function(req, res, next) {
this.foo();
}
module.exports = {bar,foo};
and no modification in app.js
var bla = require('./bla.js');
console.log(bla.bar());
Solution 9 - node.js
What I do is to create a standalone foo
function and reference it in both places.
That way, it prevents any issue with this
irrespective of using an arrow or regular function
function foo(req,res,next) {
return ('foo');
}
Then I can reference foo
at both places
module.exports = {
foo, // ES6 for foo:foo
bar: function(req, res, next) {
foo();
}
}