4

I have a module that I'm exporting. I need one function to call another function. Here's a simplified version of what I'm trying to do.

module.exports = {
  isEven: (number) => {
    return (number%2 == 0)
  },
  isTenEven: () => {
    return isEven(10)
  }
}

The code above throws isEven is not defined when moduleName.isTenEven() is called.

It makes sense why it fails. But how would you rewrite it? (While maintaining the singleton pattern)

0

6 Answers 6

5

Define the functions first, then export them:

const isEven = (number) => number % 2 === 0
const isTenEven = () => isEven(10)

module.exports = {
  isEven,
  isTenEven
}
Sign up to request clarification or add additional context in comments.

Comments

2

The object is only used to group the functions together. There's nothing really OO about it so define the functions separately. Construct the object at the end.

const isEven = number => number % 2 === 0;
const isTenEven = () => isEven(10);
module.exports = { isEven, isTenEven };

Comments

1

Maybe just do this? Define then export.

const isEven = number => number % 2 === 0;

module.exports = {
  isEven,
  isTenEven: () => isEven(10)
};

Comments

1

Just to add one more solution to the mix. You don't have to define the function elsewhere. Since the object declaration is complete before the function gets called, you can refer to it via module.exports or via exports like this:

module.exports = exports = {
  isEven: (number) => {
    return (number%2 === 0)
  },
  isTenEven: () => {
    return exports.isEven(10)
  }
}

If you were doing this in a lot of methods, you could define a shorter variable name for the exported object and refer to it.

3 Comments

In arrow functions, if the only statement in the body is a return statement, you can remove the brackets around it. If the arrow function only has just a single parameter, you can also remove the parenthesis surround it. So, for example, your isEven could be rewritten like this: isEven: number => number % 2 === 0. Should almost always be using strong equality === over ==, and avoid type coercion, particularly in a case like this where you're sure of the data types on both side of the operator.
@StephenMIrving - Yes, I know that. I just kept with the format that the OP used. It is a personal style choice whether you remove the braces (just like with a single statement if) and whether you surround the single argument with (). I stayed with the style that the OP themselves chose. I did change the == to === as that is the best choice here (something I didn't notice since it wasn't the point of the answer).
Ya I know the thing about arrow function formatting is a style choice, just wanted to let you know in case you were not aware. 😀👊
0

If you can afford Babel or a version of Node.js that supports import/export statements you could also do:

export const isEven = num => num % 2 === 0;
export const isTenEven = () => isEven(10);

Comments

-3

Inside JS object literal using this refers to the object itself so you can have:

module.exports = {
  isEven: (number) => {
    return (number%2 == 0)
  },
  isTenEven: function () {
    return this.isEven(10)
  }
}

6 Comments

No. Arrow functions inherit this from the lexical scope they are defined in. They don't have their own this value.
Hey aivo. I tried that before asking. It doesn't work.
Yup, missed that initially and edited right after. It should work.
This is less safe then the solutions proposed by the other answers since the function might get separated from the object (e.g. const { isEven, isTenEven } = require("./someModule.js");)
True. But since the question was "How to self-reference NodeJS Module", it is still an accurate answer.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.