369
votes

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

8
I tested your code and have no errors. The bar function returns undefined because have no return statement. Are you sure you are testing correctly?Ferchi
Tested in node version v8.12.0 and does no longer throw the error. bar has no return statement so running console.log(bla.bar()) simply returns undefinedVladNeacsu
@Ferchi thanks, I missed the same simple thing.Soumyadip Das

8 Answers

427
votes

Change this.foo() to module.exports.foo()

197
votes

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
}
127
votes

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();
  }

}
67
votes

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();
}
42
votes

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;
27
votes
const Service = {
  foo: (a, b) => a + b,
  bar: (a, b) => Service.foo(a, b) * b
}

module.exports = Service
19
votes

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

5
votes

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());