I have this code :
user.findOne( { 'email' : email }, function( err, User )
{
if ( err )
{
return done(err);
}
if ( !User )
{
return done(null, false, { error : "User not found"});
}
if ( !User.hasOwnProperty('local') || !User.local.hasOwnProperty('password') )
{
console.log("here: " + User.hasOwnProperty('local')); // displays here: false
}
if ( !User.validPass(password) )
{
return done(null, false, { error : "Incorrect Password"});
}
return done(null, User);
});
Since the app supports other kinds of authentication, I have a user model that has nested object called local which looks like
local : { password : "USERS_PASSWORD" }
So during login I want to check whether the user has provided a password but I encountered this interesting problem. My test object looks like this:
{ _id: 5569ac206afebed8d2d9e11e,
email: '[email protected]',
phno: '1234567890',
gender: 'female',
dob: Wed May 20 2015 05:30:00 GMT+0530 (IST),
name: 'Test Account',
__v: 0,
local: { password: '$2a$07$gytktl7BsmhM8mkuh6JVc3Bs/my7Jz9D0KBcDuKh01S' } }
but console.log("here: " + User.hasOwnProperty('local'));
prints here: false
Where did I go wrong?
The hasOwnProperty() method returns a boolean indicating whether the object has the specified property as its own property (as opposed to inheriting it).
Mongoose | findById() Function The findById() function is used to find a single document by its _id field. The _id field is cast based on the Schema before sending the command.
Mongoose Schema vs. Model. A Mongoose model is a wrapper on the Mongoose schema. A Mongoose schema defines the structure of the document, default values, validators, etc., whereas a Mongoose model provides an interface to the database for creating, querying, updating, deleting records, etc.
MongoDB is not schema-less. It's got flexible schema - there is a big difference. it's a matter of taste, Mongoose lets you have a typed schema with validations, if you use the driver you don't get that and will have to roll your own.
It's because the document object you get back from mongoose doesn't access the properties directly. It uses the prototype chain hence hasOwnProperty
returning false (I am simplifying this greatly).
You can do one of two things: use toObject()
to convert it to a plain object and then your checks will work as is:
var userPOJO = User.toObject();
if ( !(userPOJO.hasOwnProperty('local') && userPOJO.local.hasOwnProperty('password')) ) {...}
OR you can just check for values directly:
if ( !(User.local && User.local.password) ) {...}
Since neither properties can have a falsy value it should work for testing if they are populated.
EDIT: Another check I forgot to mention is to use Mongoose's built in get
method:
if (!User.get('local.password')) {...}
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