In this video we're going to continue to build out our user and task models as we explore two very important
topics.
The first is data validation and the second is data sanitization.
So with validation we can enforce that the data conforms to some rules.
As an example I could say that the users age needs to be greater than or equal to 18.
They need to be an adult data sanitization allows us to alter the data before saving it.
An example of that would be removing empty spaces around the user's name.
In this video we're going to explore both of those topics allowing us to create a more fully featured
model.
Right now we just have the basics the most bare bones version.
Let's go ahead and kick things off with some basic validation.
Now we can explore how to get all of this done and more by checking out the Mongoose docs.
Now I'm not going to lie to you.
The Mongoose docs are not the best docs in the world.
I often find it a bit difficult to track down what I'm looking for but hopefully by me pointing you
in the right direction you'll be able to learn what's covered here and figure out how the docs work
so you can use them in the future to explore other features.
Now when it comes to validation we have a validation guide over here in the left hand side which is
going to work us through some of the basic validations we can perform.
The first is going to be to set up some of our fields to be required so by default we don't have to
provide all of those fields when creating a new instance of a model using the required validation.
We can enforce that certain fields have to be provided while others could be optional so down below
if we scroll down to built in validators we can see that all types have the required validator so we
can use this for anything.
Boolean numbers strings and others and it works a little bit like this to customize the field further.
We just provide other properties on the object for the given field.
So here I'm continuing to customize the Name field for user and all we do is set required equal to true.
So now when I'm creating a new user I have to provide a name but I could choose to leave the age off.
Since I haven't set required to true for that let's go ahead and explore this.
I'm going to comment out the task creation and task save method call.
Down below and up above.
I'm going to bring our user back in to the mix and we're gonna go ahead and customize that data to start.
I'm just going to remove all properties altogether.
So we're going to try to create a new user with zero assigned fields.
Then down below I'm going to go ahead and run the program and I would expect this to fail.
If I do run the program we can see that things did indeed go wrong.
Then it can be difficult to pass this error object but the long and short of it here is that we are
indeed getting an error for name and we're not getting one for H.
We could go ahead and prove that further by actually just providing name.
So right here I'm going to provide the name sending an equal to something like Mike.
Once again I'm not providing the age which I shouldn't have to do and if I rerun the program it all
works as expected.
Once we dive a bit deeper into the task manager app you will learn how to pass that error object to
get useful messages out of it so the user knows what actually went wrong in this case.
We've decided to make a name required while making age completely optional.
Now it's going to depend on what exactly you are working with.
Sometimes all of your fields might be required.
Other times you'll have a mix of required and optional.
Now if we head back over to the Mongoose documentation and we keep looking at the built in validators
we can see there's not that many more numbers have min and max which is a bit limiting though nice and
strings have a few different but none of these are really going to provide these sort of validation.
You'll be looking for in a real application for example is this field actually storing a phone number.
Is this a valid email.
Is this a credit card.
No.
Things like that Mongoose wasn't supposed to have all of those built in but it does provide us with
a way to setup custom validation which is going to allow us to validate literally anything we'd like
so we can go ahead and set up a custom validator for a field using the following.
Right here I'll go ahead and set one up for the age field and all we do is provide validate validate
get set equal to a function.
I'm going to set my function up using that yes.
6 method a definition syntax.
We explored earlier and we get as the first argument the value we're validating.
So if I'm expecting it to be a number I would get that number right here.
Then I could run some validation on it as an example.
Let's go ahead and make sure people can't enter negative numbers for their age.
So right here what we want to do is throw an error if there is a problem with the value.
So I'm going to check if the value is less than the number zero.
If it is this code right here our code block is going to execute and we'll be able to throw an error
with the error message.
So throw new error using the javascript syntax for that and we can provide our message right here.
Something like age must be a positive number perfect.
Now that we have the message in place we're not going to allow negative ages into the application.
Now since we did make age optional it's OK.
Once again if you don't provide age at all.
Let's go ahead and test that out right here.
I'm gonna shut down the script.
I'm gonna start it up again and we can see that things do indeed work.
It's only when I do provide an age that it's gonna be validated right here I'll provide negative one
as my age.
So setting the age property equal to negative 1.
I'll go ahead and save the program and rerun it and hopefully things do indeed crash right here.
I'll see you around the script and what do I get.
I do get a long error.
Object printing to the screen.
And if I scroll up a bit through that output we should be able to find our message right here.
Age must be a positive number.
So while Mongoose does not provide a ton of built in validation we can indeed customize it to fit our
needs.
In this case making sure that the age is always a positive number.
Now when it comes to validating more complex things like emails phone numbers social security numbers
and others it's typically best to use a well tested library that already handles all of that or you
and there's a very popular NPM library for this.
If we Google NPM validator we're going to find the NPM validator package page we're gonna click over
to that and this is the package I recommend checking out for a more complex validation.
It's a super popular package with about one and a half million weekly downloads and it allows us to
do all sorts of interesting validations if we scroll down through the documentation.
We can get to a list of all validators.
They have things for email as an example I have is credit card sitting right here is currency.
If I keep scrolling through we have is email and other various formats.
We might want to actually validate for example hex colors hashes ISP addresses and others so the validator
library is your sort of one stop shop for that sort of thing.
Let's go ahead and install it and actually use it in the application over in the terminal.
I'm gonna shut the script down I'll run NPM I validator and we'll grab the latest version that's ten
point nine point zero and once we have this installed we're just going to require it and we're gonna
set up a new field for the user.
We're gonna set up an email field and we're going to enforce a valid email address so down below things
did install correctly.
Let's go ahead and actually integrate it into the application.
First up let's go ahead and load it in.
So up at the very top of the file what I'm going to do is important const validator and we are going
to require the library validator which we just installed and down below we can set up an email field.
So right here I can set up email value being an object and then we can customize that field.
I can say the type is a string.
I'm also going to set required equal to true for this one.
You have to provide an email address to register then down below.
I can set up my validate method.
I'm going to set up validate as a function and as we already know we're going to get the value right
here and we're going to use that validator library.
So all of those methods we explored in the NPM documentation those are all accessible.
Right on the validator object we got from require.
So is email as an example just takes in the string Email and it returns either true or false.
So right here we can go ahead and use that inside a validate what I'm going to do is set up an if statement.
And once again if this if statement runs we're going to throw a new error saying that things are not
valid and the message we can use for that is email is invalid.
Perfect.
Now under what conditions is the email invalid.
Well we're going to use validator.
We're going to access the is e email method.
It has accessible to us and we're going to pass the email in which is stored in value.
So right here this is going to return true and throw the error if the email is valid.
We want the opposite.
So I'll use the logical not operator to flip that boolean value from either true to false or from false
to true.
So if we provide an invalid email is e-mail is going to return false.
We're going to flip that to true to cause the if statement to run and we're going to throw the error
message.
Now we can actually test this out down below.
Let's customize our user.
I don't need to provide the age.
So I'll take that off for the moment.
I'll set e-mail equal to Mike at which is an invalid e-mail.
Now I can go ahead and rerun the program and make sure we do indeed get our custom validation message
right here.
Let's go ahead and do just that.
I'll use the up arrow key twice to cycle through those previous commands I'll use enter to run it and
what do I get.
I do indeed get the error object printing.
And if I scroll up a ways we can dig in to the actual message right here.
Email is invalid.
So being able to use the custom validator is going to allow us to define our own logic or we're gonna
be able to use other libraries that have predefined logic to validate things that are a bit more complex.
There's no need for us to write code to validate things like e-mails as there are so many edge cases
that we're gonna have to work through and we'll spend more time writing validation code than we'll actually
spend writing code specific to the task manager application.
So the theme of this class as you probably picked up on is write code specific to your app and use NPM
modules when you're doing something generic that other applications need to do as well.
There are a couple of other things that Mongoose can do for us though let's go ahead and check these
out before we move into the challenge part of the video for this one we're gonna head over to the Mongoose
documentation once again and we're going to go to schema types in the guides sidebar.
Now if we scroll down on this page we can view all of the types available to us.
We've already used string number and boolean but we have others we'll be using later throughout the
class.
We will eventually use data to track the date when things happen we'll use buffer to store profile images
for users we'll use object I.D. and array as well.
Now that we continue to scroll down on this page were eventually going to get to a list of options available
to us.
Here we can see required which we already used and validate which we've used as well.
What I want to point out for just a moment is default.
We can also choose to set a default value for a field should no value be provided you set default equal
to the default value to use.
So if it's a string I could set default equal to Anonymous.
And if someone didn't provide a name Anonymous would be used if I was working with the task model I
could use default to set the boolean completed value to a false which makes sense.
Now if we continue to scroll down don't worry we'll use default in a second.
We're gonna get two string specific options.
Here we have some ways we can sanitize our data.
We can use lower case uppercase and trim to manipulate the string before it's saved.
So I could convert the email to lower case first.
I could use trim to make sure I remove any empty spaces before or after a given value like a user's
name or a tasks description and we can see some of the other options we saw as built in.
Validators before.
So this page gives you a nice rundown on all of the things you can actually use.
Let's go ahead and use a couple of them over inside of our application then we'll move into the challenge
part of the video where you're going to continue to customize the application by customizing the task
to get started.
Let's go ahead and add a trim onto name making sure someone doesn't have a bunch of spaces as their
name.
We want to get rid of any of those leading or trailing spaces leaving us with just the actual value.
So right here trim.
True.
Perfect.
Now that's all we're going to do for a name.
Let's move on to e-mail.
So for email right after required though the order isn't important.
I can go ahead and also set trim equal to true to make sure I'm trimming spaces before or after.
I can also go ahead and use lower case by setting that equal to true to convert the email to lowercase
before saving it.
Last up we have the age now for the age.
We don't have to worry about trimming that is strings Pacific but I could go ahead and set a default
value since this field isn't required.
I could set default equal to zero.
So if you don't provide an age we'll use zero.
If you do provide an age we're gonna validate it to make sure it's a positive number.
So being able to use those properties gives us just a bit more control over the data we're allowing
into the database.
Let's go ahead and demonstrate all of this by just saving a new user one last time.
Now over in robo 3 T.
If I go over to the user's collection and refresh things we have a few different users we've created.
I'm going to go ahead and highlight all of them right click and delete those documents and over inside
of the editor we're going to update the user data.
So we have the model definition up above which is now getting pretty real world.
And down below we have our data.
So for name what I'm going to do is add some spaces followed by my name followed by some more spaces
for email.
I'm gonna go ahead and use something like my email in upper case at Mead dot I O and I'll put some spaces
after it.
And then finally for age we're not going to provide it at all.
And we're gonna see what the end result is.
Down below from the terminal we can use control C to shut things down up and enter to rerun the program
and we can see our data right here.
These spaces have been removed from name.
I have an age value of zero and my email has also had those spaces removed and it's been converted to
lower case.
So being able to have Mongoose do that for all of the data we save is gonna make sure the data we save
is consistent and valid.
Now as is my style.
This one's ran a bit longer than I wanted it to as well but it made sense to talk about all of this
at the exact same time since they are all closely related.
You are going to have a challenge where you're gonna have to use this stuff inside of a mongoose model
but I'm gonna make that the next video.
So let's go ahead and jump right in to that challenge.
Video.