I have this Mongoose schema in a Nodejs application:
const mongoose = require('mongoose'),
Schema = mongoose.Schema,
sodium = require('sodium').api;
const UserSchema = new Schema({
username: {
type: String,
required: true,
index: { unique: true }
},
salt: {
type: String,
required: false
},
password: {
type: String,
required: true
}
});
UserSchema.methods.comparePassword = function(candidatePassword, targetUser) {
let saltedCandidate = candidatePassword + targetUser.salt;
if (sodium.crypto_pwhash_str_verify(saltedCandidate, targetUser.password)) {
return true;
};
return false;
};
module.exports = mongoose.model('User', UserSchema);
And I created this routes file.
const _ = require('lodash');
const User = require('../models/user.js'); // yes, this is the correct location
module.exports = function(app) {
app.post('/user/isvalid', function(req, res) {
User.find({ username: req.body.username }, function(err, user) {
if (err) {
res.json({ info: 'that user name or password is invalid. Maybe both.' });
};
if (user) {
if (User.comparePassword(req.body.password, user)) {
// user login
res.json({ info: 'login successful' });
};
// login fail
res.json({ info: 'that user name or password is invalid Maybe both.' });
} else {
res.json({ info: 'that user name or password is invalid. Maybe both.' });
};
});
});
};
I then use Postman to make a call to 127.0.0.1:3001/user/isvalid
with an appropriate Body content. The terminal says tell me TypeError: User.comparePassword is not a function
and crashes the app.
Since the if (user)
bit passes, that indicates to me that I have properly retrieved a document from Mongo and have an instance of the User schema. Why is the method not valid?
eta: the module export I failed to copy/paste originally
This creates instance method:
UserSchema.methods.comparePassword = function(candidatePassword, targetUser) {
// ...
};
If you want a static method use this:
UserSchema.statics.comparePassword = function(candidatePassword, targetUser) {
// ...
};
Static methods are when you want to call it as User.comparePassword()
.
Instance methods are when you want to call it as someUser.comparePassword()
(which in this case would make a lot of sense so that you wouldn't have to pass the user instance explicitly).
See the documentation:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With