muthu
muthu

Reputation: 803

why mongoose validator not validating field type?

I am trying to validate mongoose schema, but i could not able to understand one thing which is a validation of type. I am passing number type to a string field and expecting it to fail in validation but it passes. how that is happening, can anyone please explain the logic behind this?

sample.js

const mongoose = require('mongoose');

async function validateSample(sample) {
  try {
    await sample.validate();
    return true;
  } catch (error) {
    return false;
  }
}

async function execMethod(){
  var userSchema = new mongoose.Schema({
    phone: {
      type: String,
      minlength: 2,
      maxlength: 4,
      validate: {
        validator: function(v) {
          return /^\d+$/.test(v);
        },
        message: `not a valid phone number!`
      },
      required: [true, 'User phone number required']
    }
  });
  
  var User = mongoose.model('user', userSchema);
  var validUser = new User({phone: '1234'});
  var invalidUser = new User({phone: 1235});
  const result = await validateSample(validUser);
  const result1 = await validateSample(invalidUser);
  console.log(result);  // true
  console.log(result1)  // expected false as number type is assigned to phone. But returns true, why?
}

execMethod()


Upvotes: 2

Views: 1225

Answers (1)

raina77ow
raina77ow

Reputation: 106483

That's actually a feature of Mongoose validation.

Before running validators, Mongoose attempts to coerce values to the correct type. This process is called casting the document. If casting fails for a given path, the error.errors object will contain a CastError object.

Casting runs before validation, and validation does not run if casting fails.

In this case, a number 1235 gets cast to a string '1235', which passed the validation just fine.

Now, there's a FR open for providing Mongoose with ability to override cast logic (either disable it completely or customize), but it's Open, not implemented.

Another way is altering casting type-wide (allowed since 5.4), like this:

mongoose.Schema.Types.String.cast(false); // prevents all casts to string

... but it might be cumbersome, as the same rule's applied to all the objects.

Upvotes: 2

Related Questions