‫Next up, let's talk about custom validators.
‫So sometimes the built-in validators are simply not enough.
‫And in that case,
‫we can also build our own custom validators.
‫And a validator is actually really just a simple function
‫which should return either true or false.
‫And if it returns false, then it means there is an error.
‫And on the other hand when we return true,
‫then the validation is correct
‫and the input can be accepted.
‫Okay, so let's now build a simple custom validator here.
‫And what I want to validate is if the price discount
‫is actually lower than the price itself.
‫That's something that we cannot do
‫using the built-in validators
‫and so we're simply gonna build our own.
‫We need to now specify here an object
‫for the SchemaType options.
‫Alright.
‫So the type is number,
‫and then to specify our validator
‫we use the validate property.
‫Validate, and then as I said,
‫a simple callback function.
‫And again, not an arrow function,
‫but a real function,
‫because in this function
‫we're gonna have access to the this variable,
‫which will point to the current document.
‫Now if you didn't need the this variable,
‫then you could of course just use an arrow function.
‫We have a callback function,
‫and that callback function actually has access
‫to the value that was inputted.
‫So in this case, the price discount that the user specified.
‫So that's what I call the value, val for short.
‫Remember that we need to return either
‫true or false from this validator.
‫When do we want to return false,
‫and when do we want to return true?
‫Well, we want an error when the price discount
‫is greater or equal than the price.
‫And so basically what we want to return here
‫is the test of testing
‫if the value is less than this.price.
‫All right, so let's say that the price discount
‫is 100 and that the real price is 200.
‫100 is less than 200, true and so we have no error.
‫And that makes sense because that's exactly what we want.
‫The price discount should always be lower.
‫On the other hand, if the discount is 250,
‫then this turns out to be false.
‫And then false, remember, will trigger a validation error.
‫Let's now test it out actually.
‫Price
‫(keyboard clacking)
‫and price discount.
‫And let's use the values that we used before
‫and I also need to change the name here.
‫Okay, so right now our discount is greater than the price
‫and so we should get our error.
‫Okay and indeed, we have a validation error.
‫So failed for path price discount.
‫Now, we do not have any custom message here
‫and so let's quickly fix that.
‫All right and the way we do that is in a very similar way
‫as we did with the enum.
‫So we need to actually specify another object
‫and then set the message property.
‫Validate
‫should be an object
‫and then we have our message in there
‫and this function here will live
‫in a property called validator.
‫Okay and our message here will be
‫(keyboard clacking)
‫discount price
‫should be
‫below the regular price.
‫Here we need a comma and so now we're good.
‫And actually, one very nice trick is that this message here
‫also has access to the value.
‫And this works in kind of a weird way
‫and this really is internal to Mongoose,
‫so this has nothing to do with JavaScript
‫so I can simply use the curly braces here and then value.
‫So this piece here will get access
‫to the value that was inputted,
‫so it has the exact same value as this val variable.
‫So let's test that again
‫and now indeed we get our message
‫and even access to the 250 price that we specified here.
‫Now let's change it to 100 and so now it should work
‫and yeah, it does.
‫So, great.
‫Now there is one very important caveat
‫that we need to notice here
‫and that is that inside a validator function,
‫that this key word is only gonna point
‫to the current document
‫when we are creating a new document.
‫So this function here is not going to work on update.
‫And so that's very important to note.
‫You see, that in Mongoose, there are a couple of caveats
‫that you really need to be aware of
‫when working with it.
‫And I learned all of these by experience
‫and so that's why now I'm able to tell them to you.
‫So I run into an error once with this one
‫and so from that time on,
‫I know that I can only use this kind of validator
‫with a this keyword in there
‫when I'm actually creating new documents.
‫So let me write that down here for you.
‫(keyboard clacking)
‫All right, so I hope that you're kind of taking note
‫of all of these very important small pieces of information
‫that are very important.
‫The same thing down here.
‫Remember that where I told you that
‫this DOCUMENT MIDDLEWARE only really runs for save
‫and create but not for update.
‫And that's one of these other things
‫that are really important to never forget.
‫Now in this specific case here,
‫there are actually ways around fixing this
‫but they're very complicated and not really worth pursuing.
‫And we could of course also write validator functions
‫that do not rely on a this variable.
‫So in this case, we only need it because we are comparing
‫one value with the value of another field.
‫This is a custom validator that we can use in Mongoose
‫and that we did actually write ourself.
‫But also, there are a couple of libraries on npm
‫for data validation that we can simply plug in here
‫as custom validators that we do not have to write ourselves.
‫And the most popular library is called validator
‫and so let's actually take a look at that one.
‫Validator and then I'm searching for GitHub
‫because usually all of these libraries are always on GitHub.
‫And the documentation is also gonna be there
‫and so here you see
‫that validator
‫is a library of string validators and sanitizers.
‫You also see that it's quite popular with 13,00 stars
‫and so
‫that's very good.
‫We also see this library validates
‫and sanitize only strings.
‫Here is then all of the stuff how we install it
‫and how we use it but that's kind of simple.
‫We already know that.
‫But what I want to show you is the list
‫of all the available validators.
‫For example, we have isAlpha,
‫which is gonna check if the string contains only letters.
‫We have Alphanumeric so only letters and numbers
‫and we really have a lot of stuff here.
‫So check if a string is boolian,
‫or check if the string is a credit card,
‫so valid credit card number.
‫Or if it's a currency
‫or you see really all kinds of different tests.
‫For example an ISBN, so for checking book numbers.
‫To test if it's an integer or if the string is lowercase.
‫And so you see, whenever you need some data validation
‫you can grab one of these libraries
‫and simply plug them into your Mongoose validators.
‫Now many of the things that are here
‫are actually already built into Mongoose
‫and so we don't need all of them, okay,
‫but there is one very specific,
‫which I want to use, which is isAlpha.
‫So I want to check if the tour name only contains letters.
‫And so for that I can use this function
‫from the validator library.
‫Let's go back
‫and start by installing
‫npm
‫i
‫(keyboard clacking)
‫validator.
‫That was successful.
‫Then I need to import it here
‫and so now we're good to go to actually use it here.
‫I'm gonna use it here
‫and again, I use the validate property
‫and now all I need to do
‫is to really plug in the function here.
‫And in validator, it works like this,
‫where validator is an object
‫and on there we have then all these methods.
‫Validator
‫is
‫Alpha,
‫so that's the one that we just choose
‫from the documentation.
‫And that's actually it.
‫So we don't call it here.
‫We basically just specify
‫that this is a function that should be used.
‫Just like our own one, like our own validator,
‫we didn't call it.
‫We simply put this callback function here
‫that it's gonna be called
‫as soon as the data should be validated.
‫And so here, it's the same.
‫Now, if we wanna specify an error message,
‫it works just like up here.
‫We can specify an array and then the error message
‫after the callback function.
‫And we could have done it down here.
‫So here we did it differently.
‫Here we then created this new object
‫with validator in there and the message,
‫but we could've done it with an array as well,
‫but that would've looked weird.
‫But up here, since the function is so small,
‫so this is so small, we can simply put it here
‫and then as a second argument in the array
‫add the error message.
‫Tour name must only contain
‫(keyboard clacking) ‫characters.
‫Great, check that out.
‫Back in Postman here, let's get rid of our price discount.
‫And let's add some number here.
‫And so that should then fail the test
‫and indeed, the name must only contain characters.
‫Let's get rid of that.
‫We can also not use this name.
‫We already used it before,
‫so that can be write out too here with characters
‫and we still get this error here.
‫Well, that's probably because of the spaces.
‫So let's just get rid of the spaces,
‫which of course is not gonna be real useful
‫and indeed, now it works.
‫So the problem was the spaces,
‫but obviously we want to keep the spaces here.
‫In fact, this validation error is not really useful
‫and so I will get rid of it.
‫Consider that this here was only to demonstrate
‫that we can use an external library like this
‫to perform validation.
‫And actually, we will still use this library a bit later
‫when we check if the user email is actually valid.
‫So that's another nice function
‫that is included in this library.
‫So again, this is how it works.
‫Not really useful in this case,
‫so if we really wanted to test
‫if the string only contains letters and spaces
‫it would probably be simpler
‫to simply use a regular expression
‫to test for that kind of pattern.
‫But I'm not gonna do that here
‫because this lecture was more about
‫these custom validators.
‫Anyway, with this lecture, we are now ready
‫with the introduction to Mongoose.
‫Now as you can imagine, there is of course
‫still a lot to learn about Mongoose
‫and in fact, we have a advanced Mongoose section
‫a bit later in the course
‫and of course also in the other sections,
‫you will keep learning more and more
‫about how to use Mongoose
‫in a real professional way.
‫You have already learned so much up until this point,
‫so huge congratulations for making it this far
‫and it's great to see that you're still with me here.
‫So great job and I hope to see you soon.