Antoine Drian
Antoine Drian

Reputation: 41

NodeJs mongoose CastError on method findById

I have a problem with mongoose, when i use the method findByIdi receive error : CastError: Cast to ObjectId failed for value "protected" at path "_id"

My _id is valid tested by mongoose.Types.ObjectId.isValid(_id);

I also tested to convert my string _id to ObjectId: mongoose.Types.ObjectId(_id) same error...

My Model is :

var UserSchema = new Schema({
  _id: {type:ObjectIdSchema, default: function () { return new ObjectId()} },
  email: { type: String, unique: true, required: true },
  pseudonyme: { type: String, unique: true, required: true },
  password: { type: String, required: true }})

I use node v6.7.0 and mongoose v4.6.5

Thks in advance for your help,

Full Code :

const jwtLogin = new JwtStrategy(jwtOptions, function(payload, done) {  
  //payload { _id: "58109f58e1bc7e3f28751cdb",email: "[email protected]",exp: 1477494763,firstName: "antoine",iat: 1477484683,lastName: "drian"}
  var isValid = mongoose.Types.ObjectId.isValid(payload._id);
  if(!isValid) done(null, false);

  var ObjectId = mongoose.Types.ObjectId;


  var _id = ObjectId(payload._id);

  User.findById( _id , function(err, user) {
    if (err) { return done(err, false); }

    if (user) {
      done(null, user);
    } else {
      done(null, false);
    }
  });
});

models/User.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectIdSchema = Schema.ObjectId;
var ObjectId = mongoose.Types.ObjectId;

var bcrypt = require('bcrypt');

// set up a mongoose model
var UserSchema = new Schema({
   // _id: {type: Schema.Types.ObjectId, auto: true},
    email: { type: String, unique: true, required: true },
    pseudonyme: { type: String, unique: true, required: true },
    password: { type: String, required: true },
    profile: {
        firstName: { type: String, required: true },
        lastName: { type: String, required: true },
        birthdate: { type: Date },
        gender: { type: String, enum: ['Male', 'Female'] },
    }
}, {
    timestamps: true
});

UserSchema.pre('save', function(next) {
    var user = this;
    if (this.isModified('password') || this.isNew) {
        bcrypt.genSalt(10, function(err, salt) {
            if (err) {
                return next(err);
            }
            bcrypt.hash(user.password, salt, function(err, hash) {
                if (err) {
                    return next(err);
                }
                user.password = hash;
                next();
            });
        });
    } else {
        return next();
    }
});

UserSchema.methods.comparePassword = function(passw, cb) {
    bcrypt.compare(passw, this.password, function(err, isMatch) {
        if (err) {
            return cb(err);
        }
        cb(null, isMatch);
    });
};

module.exports = mongoose.model('User', UserSchema);

Upvotes: 0

Views: 765

Answers (3)

Antoine Drian
Antoine Drian

Reputation: 41

I found the solution it was just a route conflict between two routes with ExpressJS.

There is no relation between the both.

Thks all people for your help

Upvotes: 1

lefdilia
lefdilia

Reputation: 170

first don't define _id in your Schema, and change 'isValid', use this instead

var UserSchema = new Schema({
  email: { type: String, unique: true, required: true },
  pseudonyme: { type: String, unique: true, required: true },
  password: { type: String, required: true }
})

and if is there an error keep it as first parameter EX : done(err) otherwise use null, EX: done(null, result)

const jwtLogin = new JwtStrategy(jwtOptions, function(payload, done) {  

var _id = mongoose.mongo.ObjectId(payload._id);

  User.find( {_id : _id} , function(err, user) {
        if (err) { return done(err); }

    if (user) {
      done(null, user);
    } else {
      done(new Error('User not found!!!'));
    }
  });
});

Upvotes: 0

hzitoun
hzitoun

Reputation: 5832

Try removing the _id from your schema.

  var UserSchema = new Schema({
      email: { type: String, unique: true, required: true },
       pseudonyme: { type: String, unique: true, required: true },
       password: { type: String, required: true }
  });

Try using the playload_id directly without casting it like below

 User.findById( payload._id , function(err, user) {
    if (err) { return done(err, false); }

    if (user) {
      done(null, user);
    } else {
      done(null, false);
    }
  });

Upvotes: 0

Related Questions