Reputation: 459
I am writing validations for user schema entries in mongoose. I want to make any one of two entries (password, googleId) required in the schema, but not both the entries are required. I want to make sure that user have either password or googleId. How this can be done? Following is me Schema
const UserSchema = new mongoose.Schema({
password: {
type: String,
trim: true,
required: true,
validate: (value)=>
{
if(value.includes(this.uname))
{
throw new Error("Password must not contain username")
}
}
},
googleId: {
type: String,
required: true
}
});
Upvotes: 2
Views: 9997
Reputation: 5704
What you could probably do is to add a pre validate check and then either call next or invalidate the document.
const schema = new mongoose.Schema({
password: {
type: String,
trim: true
},
googleId: {
type: String
}
});
schema.pre('validate', { document: true }, function(next){
if (!this.password && !this.googleId)
this.invalidate('passwordgoogleId'. 'One of the fields required.');
else
next();
});
I haven't tried it though.
Upvotes: 0
Reputation: 441
Mongoose schema provides a prevalidate
middleware which is used to validate the document and make any necessary modifications to it before the validation occurs.
import mongoose, { ValidationError } from "mongoose";
const UserSchema = new mongoose.Schema({
password: {
type: String,
trim: true,
googleId: {
type: String,
}
});
// This is a middleware
UserSchema.pre('validate', (next) => {
if (!this.password && !this.googleId) {
// if both are not available then throw the error
const err = new ValidationError(this);
err.errors.password = new ValidationError.ValidatorError({
message: 'At least one of password or googleId must be present.',
path: 'password',
value: this.password
});
next(err);
}
else {
next();
}
});
Upvotes: 0
Reputation: 167
You could use a custom validator :
const UserSchema = new mongoose.Schema({
password: {
type: String,
trim: true,
required: true,
validate: {
validator: checkCredentials,
message: props => `${props.value} is not a valid phone number!`
},
},
googleId: {
type: String,
required: true
}
});
function checkCredentials(value) {
if (!this.password || !this.googleId) {
return false;
}
return true;
}
Or with a pre
validation middleware
UserSchema.pre('validate', function(next) {
if (!this.password || !this.googleId) {
next(new Error('You should provide a google id or a password'));
} else {
next();
}
});
Upvotes: 2