-2

In its simplest form, here is the issue where a class will not be correctly returned exported if it is a class.

app.js

var Users = require('./users.js');
Users.find('test');

users.js

var Users = function() {
  function Users() {
    console.log('Users Initiated');
  }

  Users.prototype.find = function(username) {
    console.log(username);
  };

  return Users;

}

module.exports = Users;

The error I receive in the console

/Users/me/nodejsClassExport/app.js:2
Users.find('test');
      ^
TypeError: Object function () {
  function Users() {
    console.log('Users Initiated');
  }

  Users.prototype.find = function(username) {
    console.log(username);
  };

  return Users;

} has no method 'find'
    at Object.<anonymous> (/Users/me/nodejsClassExport/app.js:2:7)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:906:3

How do I export it correctly so it can be used without crashing?

3
  • 2
    You haven't posted enough code for anybody to see what's wrong. Commented Aug 23, 2014 at 14:35
  • possible duplicate of node.js module/export system: is it possible to export a module as a function Commented Aug 23, 2014 at 15:14
  • 1
    Your latest update makes it clear that Pointy's answer is correct. There is no User.find function, which is why you can't call it. There is a find function that will exist on instances created via new User, which is a completely different thing. Commented Aug 23, 2014 at 15:19

3 Answers 3

3

You're "Users" object is a function, a constructor apparently. You can't get to methods of a constructor's prototype from the constructor directly like that. You can however create an instance and access the prototypes that way.

var u = new Users();
u.find(whatever);

edit — now, back in the module, you've got two "Users" symbols. One is that outer function, and the other is that "Users" function declared inside it. However, what you export is the outer one, and it doesn't have a "find" method on its prototype. You can solve this problem by calling the outer "Users" function to get to the proper one. That can be done either in the module or in the client context, though I suspect you probably want it in the module:

module.exports = Users();
Sign up to request clarification or add additional context in comments.

2 Comments

I just can't seem to get this working. Please see this gist gist.github.com/krazyjakee/bc53d93eeac042865bae
@JakeCattrall ok I'll extend the answer.
1

From the documentation:

The module.exports object is created by the Module system. Sometimes this is not acceptable; many want their module to be an instance of some class. To do this assign the desired export object to module.exports. Note that assigning the desired object to exports will simply rebind the local exports variable, which is probably not what you want to do.

So replace

exports = Users;

with

module.exports = Users;

2 Comments

@JakeCattrall: There's not much more code in the question, it's still really unclear. (For instance: Are you really adding a find function as a property on your User function? Rather than on its prototype property, where it will show up on instances [not the function itself]?) Create a MCVE.
@JakeCattrall: It does indeed. It means that replacing exports = with module.exports = (above) was necessary, and that once we fixed that problem, Pointy's answer deals with the next problem.
0

There is a problem with this line:

this.users = nStore["new"]('data/users.db');

It is either not saving a new object to this.users or it falling victim to an asynchronous race condition, as it is complaining about how this.users.find() does not exist.

Likely, it is because that function for nStore takes a callback, so you'll have to consider that with the rest of your code.

this.users = nStore.new('data/users.db', function () {
  console.log('Users Initiated');
  // now it is safe to use the methods in 'this.users'
});

1 Comment

The OP isn't calling find on this.users, he's calling it on User.

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.