1 00:00:00,240 --> 00:00:07,260 In this video we're going to continue to build out our user and task models as we explore two very important 2 00:00:07,290 --> 00:00:08,250 topics. 3 00:00:08,250 --> 00:00:13,740 The first is data validation and the second is data sanitization. 4 00:00:13,740 --> 00:00:18,370 So with validation we can enforce that the data conforms to some rules. 5 00:00:18,390 --> 00:00:24,510 As an example I could say that the users age needs to be greater than or equal to 18. 6 00:00:24,510 --> 00:00:30,930 They need to be an adult data sanitization allows us to alter the data before saving it. 7 00:00:30,930 --> 00:00:36,660 An example of that would be removing empty spaces around the user's name. 8 00:00:36,750 --> 00:00:43,010 In this video we're going to explore both of those topics allowing us to create a more fully featured 9 00:00:43,020 --> 00:00:43,860 model. 10 00:00:43,860 --> 00:00:48,030 Right now we just have the basics the most bare bones version. 11 00:00:48,030 --> 00:00:52,160 Let's go ahead and kick things off with some basic validation. 12 00:00:52,170 --> 00:00:57,780 Now we can explore how to get all of this done and more by checking out the Mongoose docs. 13 00:00:57,780 --> 00:00:59,180 Now I'm not going to lie to you. 14 00:00:59,190 --> 00:01:02,850 The Mongoose docs are not the best docs in the world. 15 00:01:02,850 --> 00:01:08,670 I often find it a bit difficult to track down what I'm looking for but hopefully by me pointing you 16 00:01:08,670 --> 00:01:14,280 in the right direction you'll be able to learn what's covered here and figure out how the docs work 17 00:01:14,340 --> 00:01:18,350 so you can use them in the future to explore other features. 18 00:01:18,360 --> 00:01:24,060 Now when it comes to validation we have a validation guide over here in the left hand side which is 19 00:01:24,060 --> 00:01:28,530 going to work us through some of the basic validations we can perform. 20 00:01:28,530 --> 00:01:34,860 The first is going to be to set up some of our fields to be required so by default we don't have to 21 00:01:34,860 --> 00:01:42,190 provide all of those fields when creating a new instance of a model using the required validation. 22 00:01:42,270 --> 00:01:48,360 We can enforce that certain fields have to be provided while others could be optional so down below 23 00:01:48,360 --> 00:01:55,740 if we scroll down to built in validators we can see that all types have the required validator so we 24 00:01:55,740 --> 00:01:57,200 can use this for anything. 25 00:01:57,210 --> 00:02:04,660 Boolean numbers strings and others and it works a little bit like this to customize the field further. 26 00:02:04,680 --> 00:02:09,210 We just provide other properties on the object for the given field. 27 00:02:09,240 --> 00:02:17,940 So here I'm continuing to customize the Name field for user and all we do is set required equal to true. 28 00:02:17,940 --> 00:02:24,630 So now when I'm creating a new user I have to provide a name but I could choose to leave the age off. 29 00:02:24,630 --> 00:02:29,970 Since I haven't set required to true for that let's go ahead and explore this. 30 00:02:30,060 --> 00:02:35,220 I'm going to comment out the task creation and task save method call. 31 00:02:35,220 --> 00:02:37,590 Down below and up above. 32 00:02:37,590 --> 00:02:44,700 I'm going to bring our user back in to the mix and we're gonna go ahead and customize that data to start. 33 00:02:44,700 --> 00:02:48,210 I'm just going to remove all properties altogether. 34 00:02:48,210 --> 00:02:53,550 So we're going to try to create a new user with zero assigned fields. 35 00:02:53,610 --> 00:02:58,700 Then down below I'm going to go ahead and run the program and I would expect this to fail. 36 00:02:58,860 --> 00:03:03,150 If I do run the program we can see that things did indeed go wrong. 37 00:03:03,280 --> 00:03:09,510 Then it can be difficult to pass this error object but the long and short of it here is that we are 38 00:03:09,510 --> 00:03:14,240 indeed getting an error for name and we're not getting one for H. 39 00:03:14,280 --> 00:03:19,210 We could go ahead and prove that further by actually just providing name. 40 00:03:19,350 --> 00:03:24,960 So right here I'm going to provide the name sending an equal to something like Mike. 41 00:03:24,960 --> 00:03:30,960 Once again I'm not providing the age which I shouldn't have to do and if I rerun the program it all 42 00:03:30,960 --> 00:03:32,550 works as expected. 43 00:03:32,790 --> 00:03:39,420 Once we dive a bit deeper into the task manager app you will learn how to pass that error object to 44 00:03:39,420 --> 00:03:45,080 get useful messages out of it so the user knows what actually went wrong in this case. 45 00:03:45,090 --> 00:03:50,210 We've decided to make a name required while making age completely optional. 46 00:03:50,220 --> 00:03:53,490 Now it's going to depend on what exactly you are working with. 47 00:03:53,490 --> 00:03:56,810 Sometimes all of your fields might be required. 48 00:03:56,820 --> 00:04:00,270 Other times you'll have a mix of required and optional. 49 00:04:00,270 --> 00:04:06,360 Now if we head back over to the Mongoose documentation and we keep looking at the built in validators 50 00:04:06,570 --> 00:04:13,230 we can see there's not that many more numbers have min and max which is a bit limiting though nice and 51 00:04:13,230 --> 00:04:18,740 strings have a few different but none of these are really going to provide these sort of validation. 52 00:04:18,740 --> 00:04:25,230 You'll be looking for in a real application for example is this field actually storing a phone number. 53 00:04:25,230 --> 00:04:27,090 Is this a valid email. 54 00:04:27,090 --> 00:04:28,190 Is this a credit card. 55 00:04:28,200 --> 00:04:28,680 No. 56 00:04:28,680 --> 00:04:34,650 Things like that Mongoose wasn't supposed to have all of those built in but it does provide us with 57 00:04:34,650 --> 00:04:41,550 a way to setup custom validation which is going to allow us to validate literally anything we'd like 58 00:04:42,060 --> 00:04:46,990 so we can go ahead and set up a custom validator for a field using the following. 59 00:04:47,100 --> 00:04:54,480 Right here I'll go ahead and set one up for the age field and all we do is provide validate validate 60 00:04:54,510 --> 00:04:56,590 get set equal to a function. 61 00:04:56,640 --> 00:04:59,180 I'm going to set my function up using that yes. 62 00:04:59,190 --> 00:05:01,600 6 method a definition syntax. 63 00:05:01,630 --> 00:05:07,260 We explored earlier and we get as the first argument the value we're validating. 64 00:05:07,600 --> 00:05:12,250 So if I'm expecting it to be a number I would get that number right here. 65 00:05:12,310 --> 00:05:15,690 Then I could run some validation on it as an example. 66 00:05:15,760 --> 00:05:21,070 Let's go ahead and make sure people can't enter negative numbers for their age. 67 00:05:21,070 --> 00:05:26,650 So right here what we want to do is throw an error if there is a problem with the value. 68 00:05:26,650 --> 00:05:33,540 So I'm going to check if the value is less than the number zero. 69 00:05:33,580 --> 00:05:39,940 If it is this code right here our code block is going to execute and we'll be able to throw an error 70 00:05:40,000 --> 00:05:41,700 with the error message. 71 00:05:41,710 --> 00:05:50,560 So throw new error using the javascript syntax for that and we can provide our message right here. 72 00:05:50,620 --> 00:05:57,550 Something like age must be a positive number perfect. 73 00:05:57,630 --> 00:06:03,370 Now that we have the message in place we're not going to allow negative ages into the application. 74 00:06:03,600 --> 00:06:07,060 Now since we did make age optional it's OK. 75 00:06:07,080 --> 00:06:10,330 Once again if you don't provide age at all. 76 00:06:10,410 --> 00:06:13,540 Let's go ahead and test that out right here. 77 00:06:13,590 --> 00:06:15,270 I'm gonna shut down the script. 78 00:06:15,390 --> 00:06:19,620 I'm gonna start it up again and we can see that things do indeed work. 79 00:06:19,620 --> 00:06:25,530 It's only when I do provide an age that it's gonna be validated right here I'll provide negative one 80 00:06:25,560 --> 00:06:26,610 as my age. 81 00:06:26,640 --> 00:06:30,570 So setting the age property equal to negative 1. 82 00:06:30,720 --> 00:06:37,150 I'll go ahead and save the program and rerun it and hopefully things do indeed crash right here. 83 00:06:37,270 --> 00:06:39,510 I'll see you around the script and what do I get. 84 00:06:39,510 --> 00:06:41,620 I do get a long error. 85 00:06:41,640 --> 00:06:43,720 Object printing to the screen. 86 00:06:43,830 --> 00:06:49,280 And if I scroll up a bit through that output we should be able to find our message right here. 87 00:06:49,290 --> 00:06:52,800 Age must be a positive number. 88 00:06:52,800 --> 00:06:59,340 So while Mongoose does not provide a ton of built in validation we can indeed customize it to fit our 89 00:06:59,340 --> 00:07:00,090 needs. 90 00:07:00,090 --> 00:07:04,320 In this case making sure that the age is always a positive number. 91 00:07:04,350 --> 00:07:10,620 Now when it comes to validating more complex things like emails phone numbers social security numbers 92 00:07:10,680 --> 00:07:17,700 and others it's typically best to use a well tested library that already handles all of that or you 93 00:07:18,030 --> 00:07:21,720 and there's a very popular NPM library for this. 94 00:07:21,720 --> 00:07:31,110 If we Google NPM validator we're going to find the NPM validator package page we're gonna click over 95 00:07:31,110 --> 00:07:37,440 to that and this is the package I recommend checking out for a more complex validation. 96 00:07:37,440 --> 00:07:43,680 It's a super popular package with about one and a half million weekly downloads and it allows us to 97 00:07:43,680 --> 00:07:49,260 do all sorts of interesting validations if we scroll down through the documentation. 98 00:07:49,380 --> 00:07:52,030 We can get to a list of all validators. 99 00:07:52,080 --> 00:07:59,010 They have things for email as an example I have is credit card sitting right here is currency. 100 00:07:59,010 --> 00:08:03,750 If I keep scrolling through we have is email and other various formats. 101 00:08:03,750 --> 00:08:12,450 We might want to actually validate for example hex colors hashes ISP addresses and others so the validator 102 00:08:12,450 --> 00:08:16,410 library is your sort of one stop shop for that sort of thing. 103 00:08:16,470 --> 00:08:22,050 Let's go ahead and install it and actually use it in the application over in the terminal. 104 00:08:22,050 --> 00:08:30,340 I'm gonna shut the script down I'll run NPM I validator and we'll grab the latest version that's ten 105 00:08:30,400 --> 00:08:36,600 point nine point zero and once we have this installed we're just going to require it and we're gonna 106 00:08:36,610 --> 00:08:39,490 set up a new field for the user. 107 00:08:39,580 --> 00:08:47,320 We're gonna set up an email field and we're going to enforce a valid email address so down below things 108 00:08:47,320 --> 00:08:48,820 did install correctly. 109 00:08:49,090 --> 00:08:52,300 Let's go ahead and actually integrate it into the application. 110 00:08:52,300 --> 00:08:54,640 First up let's go ahead and load it in. 111 00:08:54,660 --> 00:09:02,770 So up at the very top of the file what I'm going to do is important const validator and we are going 112 00:09:02,770 --> 00:09:09,160 to require the library validator which we just installed and down below we can set up an email field. 113 00:09:09,520 --> 00:09:16,800 So right here I can set up email value being an object and then we can customize that field. 114 00:09:16,870 --> 00:09:19,340 I can say the type is a string. 115 00:09:19,420 --> 00:09:23,620 I'm also going to set required equal to true for this one. 116 00:09:23,620 --> 00:09:28,360 You have to provide an email address to register then down below. 117 00:09:28,360 --> 00:09:30,700 I can set up my validate method. 118 00:09:30,700 --> 00:09:36,820 I'm going to set up validate as a function and as we already know we're going to get the value right 119 00:09:36,820 --> 00:09:40,870 here and we're going to use that validator library. 120 00:09:40,870 --> 00:09:46,300 So all of those methods we explored in the NPM documentation those are all accessible. 121 00:09:46,300 --> 00:09:49,620 Right on the validator object we got from require. 122 00:09:49,870 --> 00:09:56,700 So is email as an example just takes in the string Email and it returns either true or false. 123 00:09:56,710 --> 00:10:03,640 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. 124 00:10:03,820 --> 00:10:10,450 And once again if this if statement runs we're going to throw a new error saying that things are not 125 00:10:10,450 --> 00:10:16,120 valid and the message we can use for that is email is invalid. 126 00:10:16,120 --> 00:10:17,110 Perfect. 127 00:10:17,110 --> 00:10:20,320 Now under what conditions is the email invalid. 128 00:10:20,320 --> 00:10:23,190 Well we're going to use validator. 129 00:10:23,350 --> 00:10:26,470 We're going to access the is e email method. 130 00:10:26,470 --> 00:10:32,210 It has accessible to us and we're going to pass the email in which is stored in value. 131 00:10:32,260 --> 00:10:38,530 So right here this is going to return true and throw the error if the email is valid. 132 00:10:38,530 --> 00:10:40,000 We want the opposite. 133 00:10:40,000 --> 00:10:46,540 So I'll use the logical not operator to flip that boolean value from either true to false or from false 134 00:10:46,540 --> 00:10:47,740 to true. 135 00:10:47,740 --> 00:10:53,130 So if we provide an invalid email is e-mail is going to return false. 136 00:10:53,140 --> 00:10:58,300 We're going to flip that to true to cause the if statement to run and we're going to throw the error 137 00:10:58,420 --> 00:10:59,410 message. 138 00:10:59,410 --> 00:11:02,320 Now we can actually test this out down below. 139 00:11:02,410 --> 00:11:04,220 Let's customize our user. 140 00:11:04,330 --> 00:11:06,080 I don't need to provide the age. 141 00:11:06,100 --> 00:11:08,320 So I'll take that off for the moment. 142 00:11:08,470 --> 00:11:13,210 I'll set e-mail equal to Mike at which is an invalid e-mail. 143 00:11:13,240 --> 00:11:19,660 Now I can go ahead and rerun the program and make sure we do indeed get our custom validation message 144 00:11:19,930 --> 00:11:20,620 right here. 145 00:11:20,620 --> 00:11:22,720 Let's go ahead and do just that. 146 00:11:22,780 --> 00:11:28,900 I'll use the up arrow key twice to cycle through those previous commands I'll use enter to run it and 147 00:11:28,900 --> 00:11:29,820 what do I get. 148 00:11:29,830 --> 00:11:32,560 I do indeed get the error object printing. 149 00:11:32,830 --> 00:11:37,270 And if I scroll up a ways we can dig in to the actual message right here. 150 00:11:37,270 --> 00:11:39,280 Email is invalid. 151 00:11:39,280 --> 00:11:45,630 So being able to use the custom validator is going to allow us to define our own logic or we're gonna 152 00:11:45,640 --> 00:11:52,270 be able to use other libraries that have predefined logic to validate things that are a bit more complex. 153 00:11:52,270 --> 00:11:58,660 There's no need for us to write code to validate things like e-mails as there are so many edge cases 154 00:11:58,660 --> 00:12:04,390 that we're gonna have to work through and we'll spend more time writing validation code than we'll actually 155 00:12:04,390 --> 00:12:09,370 spend writing code specific to the task manager application. 156 00:12:09,370 --> 00:12:16,870 So the theme of this class as you probably picked up on is write code specific to your app and use NPM 157 00:12:16,870 --> 00:12:22,120 modules when you're doing something generic that other applications need to do as well. 158 00:12:22,120 --> 00:12:27,310 There are a couple of other things that Mongoose can do for us though let's go ahead and check these 159 00:12:27,310 --> 00:12:33,130 out before we move into the challenge part of the video for this one we're gonna head over to the Mongoose 160 00:12:33,130 --> 00:12:39,820 documentation once again and we're going to go to schema types in the guides sidebar. 161 00:12:39,820 --> 00:12:44,390 Now if we scroll down on this page we can view all of the types available to us. 162 00:12:44,420 --> 00:12:50,170 We've already used string number and boolean but we have others we'll be using later throughout the 163 00:12:50,170 --> 00:12:51,070 class. 164 00:12:51,070 --> 00:12:57,790 We will eventually use data to track the date when things happen we'll use buffer to store profile images 165 00:12:57,820 --> 00:13:02,660 for users we'll use object I.D. and array as well. 166 00:13:02,800 --> 00:13:08,800 Now that we continue to scroll down on this page were eventually going to get to a list of options available 167 00:13:08,800 --> 00:13:09,550 to us. 168 00:13:09,550 --> 00:13:15,250 Here we can see required which we already used and validate which we've used as well. 169 00:13:15,250 --> 00:13:18,640 What I want to point out for just a moment is default. 170 00:13:18,640 --> 00:13:26,350 We can also choose to set a default value for a field should no value be provided you set default equal 171 00:13:26,410 --> 00:13:28,930 to the default value to use. 172 00:13:28,930 --> 00:13:32,680 So if it's a string I could set default equal to Anonymous. 173 00:13:32,680 --> 00:13:39,310 And if someone didn't provide a name Anonymous would be used if I was working with the task model I 174 00:13:39,310 --> 00:13:44,530 could use default to set the boolean completed value to a false which makes sense. 175 00:13:44,530 --> 00:13:49,030 Now if we continue to scroll down don't worry we'll use default in a second. 176 00:13:49,090 --> 00:13:51,890 We're gonna get two string specific options. 177 00:13:51,970 --> 00:13:55,000 Here we have some ways we can sanitize our data. 178 00:13:55,060 --> 00:14:01,650 We can use lower case uppercase and trim to manipulate the string before it's saved. 179 00:14:01,690 --> 00:14:05,250 So I could convert the email to lower case first. 180 00:14:05,320 --> 00:14:12,940 I could use trim to make sure I remove any empty spaces before or after a given value like a user's 181 00:14:12,940 --> 00:14:18,730 name or a tasks description and we can see some of the other options we saw as built in. 182 00:14:18,730 --> 00:14:20,290 Validators before. 183 00:14:20,370 --> 00:14:24,910 So this page gives you a nice rundown on all of the things you can actually use. 184 00:14:25,240 --> 00:14:30,670 Let's go ahead and use a couple of them over inside of our application then we'll move into the challenge 185 00:14:30,670 --> 00:14:36,910 part of the video where you're going to continue to customize the application by customizing the task 186 00:14:37,000 --> 00:14:37,870 to get started. 187 00:14:37,900 --> 00:14:43,840 Let's go ahead and add a trim onto name making sure someone doesn't have a bunch of spaces as their 188 00:14:43,840 --> 00:14:44,560 name. 189 00:14:44,560 --> 00:14:49,960 We want to get rid of any of those leading or trailing spaces leaving us with just the actual value. 190 00:14:50,020 --> 00:14:51,710 So right here trim. 191 00:14:51,870 --> 00:14:52,550 True. 192 00:14:52,600 --> 00:14:53,700 Perfect. 193 00:14:53,720 --> 00:14:55,240 Now that's all we're going to do for a name. 194 00:14:55,240 --> 00:14:57,160 Let's move on to e-mail. 195 00:14:57,160 --> 00:15:01,300 So for email right after required though the order isn't important. 196 00:15:01,300 --> 00:15:08,440 I can go ahead and also set trim equal to true to make sure I'm trimming spaces before or after. 197 00:15:08,500 --> 00:15:15,310 I can also go ahead and use lower case by setting that equal to true to convert the email to lowercase 198 00:15:15,340 --> 00:15:16,630 before saving it. 199 00:15:16,930 --> 00:15:20,050 Last up we have the age now for the age. 200 00:15:20,050 --> 00:15:25,290 We don't have to worry about trimming that is strings Pacific but I could go ahead and set a default 201 00:15:25,290 --> 00:15:28,230 value since this field isn't required. 202 00:15:28,230 --> 00:15:31,970 I could set default equal to zero. 203 00:15:32,040 --> 00:15:35,300 So if you don't provide an age we'll use zero. 204 00:15:35,310 --> 00:15:40,080 If you do provide an age we're gonna validate it to make sure it's a positive number. 205 00:15:40,080 --> 00:15:46,440 So being able to use those properties gives us just a bit more control over the data we're allowing 206 00:15:46,530 --> 00:15:47,960 into the database. 207 00:15:47,970 --> 00:15:53,310 Let's go ahead and demonstrate all of this by just saving a new user one last time. 208 00:15:53,310 --> 00:15:55,690 Now over in robo 3 T. 209 00:15:55,860 --> 00:16:01,950 If I go over to the user's collection and refresh things we have a few different users we've created. 210 00:16:01,950 --> 00:16:08,780 I'm going to go ahead and highlight all of them right click and delete those documents and over inside 211 00:16:08,780 --> 00:16:12,110 of the editor we're going to update the user data. 212 00:16:12,200 --> 00:16:17,360 So we have the model definition up above which is now getting pretty real world. 213 00:16:17,360 --> 00:16:19,100 And down below we have our data. 214 00:16:19,460 --> 00:16:25,940 So for name what I'm going to do is add some spaces followed by my name followed by some more spaces 215 00:16:26,570 --> 00:16:27,290 for email. 216 00:16:27,290 --> 00:16:34,700 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 217 00:16:34,760 --> 00:16:35,870 after it. 218 00:16:35,870 --> 00:16:39,330 And then finally for age we're not going to provide it at all. 219 00:16:39,380 --> 00:16:42,490 And we're gonna see what the end result is. 220 00:16:42,620 --> 00:16:49,940 Down below from the terminal we can use control C to shut things down up and enter to rerun the program 221 00:16:50,180 --> 00:16:52,400 and we can see our data right here. 222 00:16:52,400 --> 00:16:54,950 These spaces have been removed from name. 223 00:16:55,160 --> 00:17:01,640 I have an age value of zero and my email has also had those spaces removed and it's been converted to 224 00:17:01,640 --> 00:17:02,800 lower case. 225 00:17:02,840 --> 00:17:08,750 So being able to have Mongoose do that for all of the data we save is gonna make sure the data we save 226 00:17:08,780 --> 00:17:10,770 is consistent and valid. 227 00:17:10,770 --> 00:17:12,350 Now as is my style. 228 00:17:12,350 --> 00:17:18,380 This one's ran a bit longer than I wanted it to as well but it made sense to talk about all of this 229 00:17:18,380 --> 00:17:22,340 at the exact same time since they are all closely related. 230 00:17:22,370 --> 00:17:28,400 You are going to have a challenge where you're gonna have to use this stuff inside of a mongoose model 231 00:17:28,580 --> 00:17:30,760 but I'm gonna make that the next video. 232 00:17:30,890 --> 00:17:33,800 So let's go ahead and jump right in to that challenge. 233 00:17:33,800 --> 00:17:34,280 Video.