Reputation: 4416
The Stripe Rocket Rides demo uses isAsync
in a validator:
// Make sure the email has not been used.
PilotSchema.path('email').validate({
isAsync: true,
validator: function(email, callback) {
const Pilot = mongoose.model('Pilot');
// Check only when it is a new pilot or when the email has been modified.
if (this.isNew || this.isModified('email')) {
Pilot.find({ email: email }).exec(function(err, pilots) {
callback(!err && pilots.length === 0);
});
} else {
callback(true);
}
},
message: 'This email already exists. Please try to log in instead.',
});
This method throws an error with a reference
DeprecationWarning: Mongoose: the `isAsync` option for custom validators is deprecated. Make your async validators return a promise instead: https://mongoosejs.com/docs/validation.html#async-custom-validators
The MongoDB page quoted has this code:
const userSchema = new Schema({
name: {
type: String,
// You can also make a validator async by returning a promise.
validate: () => Promise.reject(new Error('Oops!'))
},
email: {
type: String,
// There are two ways for an promise-based async validator to fail:
// 1) If the promise rejects, Mongoose assumes the validator failed with the given error.
// 2) If the promise resolves to `false`, Mongoose assumes the validator failed and creates an error with the given `message`.
validate: {
validator: () => Promise.resolve(false),
message: 'Email validation failed'
}
}
});
I am new to NodeJS and I don't see how to adapt the MongoDB code to the Rocket Rides demo. Neither Implicit async custom validators (custom validators that take 2 arguments) are deprecated in mongoose >= 4.9.0 nor Mongoose custom validation for password helped.
How can I verify the uniqueness of email addresses and avoid that error?
Upvotes: 0
Views: 1545
Reputation: 71
try this, I had the same problem.
To fix it use a separate async function that you call with await.
// Make sure the email has not been used.
PilotSchema.path('email').validate({
validator: async function(v) {
return await checkMailDup(v, this);
},
message: 'This email already exists. Please try to log in instead.',
});
async function checkMailDup(v, t) {
const Pilot = mongoose.model('Pilot');
// Check only when it is a new pilot or when the email has been modified.
if (t.isNew || t.isModified('email')) {
try {
const pilots = await Pilot.find({ email: v });
return pilots.length === 0;
} catch (err) {
return false;
}
} else {
return true;
}
}
Let me know if it works.
I used the following references:
Cheers!
Upvotes: 3