Search code examples
javascriptnode.jsrevealing-module-pattern

Requiring a module that uses the revealing module pattern


I am trying the require a module that is a self invoking Javascript function, and passing it a parameter when I require it. The 'required' object is always saying 'object is not a function'.

Is the following code possible, and if so where I am going wrong?

Module

var _ = require('lodash');

var userRepository = (function(userRecords) {

  console.log(userRecords);

  var findByUsername = function(username, cb) {

    //find username in the userNameData
    //this may have been retrieved from the DB or passed in as mock data from the tests
    var user = _.find(userRecords, {
      "email": username
    });

    if (user) {
      return cb(null, user);
    } else {
      return cb(null, null);
    }
  };

  return {
    findByUserName: findByUsername
  };

})();

module.exports = userRepository;

Usage in code

var userData = require('../test/data/users.json'),
  userRepository = require('../db/userRepository')(userData);


describe('User Repository', function() {
  describe('Find by username', function() {
    it('should return a user record for <user> if the username <username> is found', function() {
      var username = "test@testing.com";
      var user = userRepository.findByUsername(username, function() {});
    });
  });
});

Thanks in advance for any help


Solution

  • userRepository is an IIFE, which returns an object, so when you require it, you receive this object - which, alas, is not a function.

    I see you're trying to invoke findByUserName, which is indeed a "public" function on this object, just change your require line to the following:

    userRepository = require('../db/userRepository');
    

    After this line, userRepository will be the object your IIFE returned. Then you can call userRepository.findByUserName() (as you are in your sample) without any further modifications to your code.

    If you want userRepository to take userRecord as a parameter (as per your comment), don't use a self-invoking function, just export the function that's currently self-invoking.

    (Intuitively: if you want userRecord to be supplied from outside the module, you can't have this function self-invoke, you need to export the function itself to make it available to users of your module - so that they can call it with the userRecord that they have.)