The Problem:
I have a basic authentication flow set up. I have this custom method on my users model:
userSchema.methods.joiValidate = function() {
console.log(typeof this.username);
const Joi = require("joi");
const schema = {
username: Joi.types.String.min(6)
.max(24)
.required(),
email: Joi.types.String.email().required(),
password: Joi.types.String.min(8)
.max(30)
.regex(/[a-zA-Z0-9]{3,30}/)
.required()
};
return Joi.validate(this, schema);
};
But it isn't working as expected.
When I create a new user and validate it like so:
const invalidUser = new User({
username: "bob",
email: "test@gmail.com",
password: "test123"
});
invalidUser.joiValidate();
I get this error message: TypeError: Cannot read property 'String' of undefined
I don't know why? this
in my method refers to exact this user and it has all required fields on it (username, email and password) when I console.log it in the model (document) itself.
I also tried to Joi.validate(this.toObject(), schema)
on the method but that doesn't change anything.
Could anybody explain me what is going on and why it's not working?
For anyone curious what the problem was - I somehow messed up the whole syntax of joi (Copied some old code I found on StackOverflow, LOL).
I fixed it like this:
userSchema.methods.joiValidate = function() {
// pull out just the properties that has to be checked (generated fields from mongoose we ignore)
const { username, email, password } = this;
const user = { username, email, password };
const Joi = require("joi");
const schema = Joi.object().keys({
username: Joi.string()
.min(6)
.max(24)
.required(),
email: Joi.string()
.email()
.required(),
password: Joi.string()
.min(8)
.max(30)
.regex(/[a-zA-Z0-9]{3,30}/)
.required(),
_id: Joi.string()
});
return Joi.validate(user, schema, { abortEarly: false });
};