Class methods in node.js
Solution 1
A couple of things are going on here, I've corrected your source code and added comments to explain along the way:
lib/User.js
// much more concise declaration
function User(db) {
this.db = db;
}
// You need to assign a new function here
User.prototype.findOne = function (email, password, fn) {
// some code here
}
// no need to overwrite `exports` ... since you're replacing `module.exports` itself
module.exports = User;
app.js
// don't forget `var`
// also don't call the require as a function, it's the class "declaration" you use to create new instances
var User = require('./lib/User');
// create a new instance of the user "class"
var user = new User(db);
// call findOne as an instance method
user.findOne(email, pw, callback);
Solution 2
You need to new User(db)
at some point.
You could make an init method
exports.init = function(db){
return new User(db)
}
And then from your code:
var User = require(...).init(db);
![Patrick](https://i.stack.imgur.com/tZlw1.jpg?s=256&g=1)
Patrick
Location independent software nerd. I love breaking down complex situations into simple and minimalistic solutions. Available for new contracts anywhere in the world. #nodejs #javascript #devops #serverless
Updated on August 03, 2020Comments
-
Patrick almost 4 years
I've been trying for the last hour to write a user module for passport.js with the findOne, findOneOrCreate, etc. methods, but can't get it right.
User.js
var User = function(db) { this.db = db; } User.prototype.findOne(email, password, fn) { // some code here } module.exports = exports = User;
app.js
User = require('./lib/User')(db); User.findOne(email, pw, callback);
I've been through dozens of errors, mostly
TypeError: object is not a function
or
TypeError: Object function () { function User(db) { console.log(db); } } has no method 'findOne'
How do I create a proper module with these functions without creating an object/instance of User?
Update
I went over the proposed solutions:
var db; function User(db) { this.db = db; } User.prototype.init = function(db) { return new User(db); } User.prototype.findOne = function(profile, fn) {} module.exports = User;
No luck.
TypeError: Object function User(db) { this.db = db; } has no method 'init'
-
Bryan over 7 yearsIn case it helps, see the answer in stackoverflow.com/questions/39932009/node-express-middleware/… that shows how to create an Express middleware function that has access to class methods. This answer assumes ES6 class is available.
-
-
Robert K almost 12 yearsYes, technically he's just imported the class reference... not instantiated it.
-
Patrick almost 12 yearsHm, ok. I was hoping I'll get around an instance. This seems to be the nicest solution. Thanks!
-
3on almost 12 yearsYou are welcome. Java people call that a factory if I'm not mistaken.
-
Patrick almost 12 yearsJepp, I went through all the patterns. It seems that some libraries do it without instance though. I updated the question, the solution doesn't quite work yet.
-
3on almost 12 yearsWell you do not have to do "classes" that you new you can just have a modular approach if you do not need multiple instance of you that particular code. by having only exports.myFunction = function() {...}. Beside you did not get my first solution.
-
Patrick almost 12 yearsOk, got it working now! I thought I still need the module.exports.
-
3on almost 12 yearsYou don't want to export the "class" you just want to exports the module method which returns you an Object User on which you have define some method in the its prototype.