﻿1
00:00:01,150 --> 00:00:04,333
‫Next up, let's talk about custom validators.

2
00:00:05,940 --> 00:00:10,110
‫So sometimes the built-in validators are simply not enough.

3
00:00:10,110 --> 00:00:11,100
‫And in that case,

4
00:00:11,100 --> 00:00:14,250
‫we can also build our own custom validators.

5
00:00:14,250 --> 00:00:18,230
‫And a validator is actually really just a simple function

6
00:00:18,230 --> 00:00:21,250
‫which should return either true or false.

7
00:00:21,250 --> 00:00:24,330
‫And if it returns false, then it means there is an error.

8
00:00:24,330 --> 00:00:26,650
‫And on the other hand when we return true,

9
00:00:26,650 --> 00:00:28,690
‫then the validation is correct

10
00:00:28,690 --> 00:00:31,260
‫and the input can be accepted.

11
00:00:31,260 --> 00:00:35,560
‫Okay, so let's now build a simple custom validator here.

12
00:00:35,560 --> 00:00:39,980
‫And what I want to validate is if the price discount

13
00:00:39,980 --> 00:00:42,863
‫is actually lower than the price itself.

14
00:00:44,440 --> 00:00:46,130
‫That's something that we cannot do

15
00:00:46,130 --> 00:00:47,980
‫using the built-in validators

16
00:00:47,980 --> 00:00:49,980
‫and so we're simply gonna build our own.

17
00:00:52,575 --> 00:00:54,690
‫We need to now specify here an object

18
00:00:54,690 --> 00:00:56,453
‫for the SchemaType options.

19
00:01:00,170 --> 00:01:01,003
‫Alright.

20
00:01:05,190 --> 00:01:07,400
‫So the type is number,

21
00:01:07,400 --> 00:01:09,880
‫and then to specify our validator

22
00:01:09,880 --> 00:01:11,853
‫we use the validate property.

23
00:01:15,270 --> 00:01:17,580
‫Validate, and then as I said,

24
00:01:17,580 --> 00:01:19,173
‫a simple callback function.

25
00:01:21,600 --> 00:01:23,840
‫And again, not an arrow function,

26
00:01:23,840 --> 00:01:25,090
‫but a real function,

27
00:01:25,090 --> 00:01:26,200
‫because in this function

28
00:01:26,200 --> 00:01:28,730
‫we're gonna have access to the this variable,

29
00:01:28,730 --> 00:01:30,983
‫which will point to the current document.

30
00:01:31,940 --> 00:01:34,540
‫Now if you didn't need the this variable,

31
00:01:34,540 --> 00:01:37,140
‫then you could of course just use an arrow function.

32
00:01:39,710 --> 00:01:41,150
‫We have a callback function,

33
00:01:41,150 --> 00:01:43,910
‫and that callback function actually has access

34
00:01:43,910 --> 00:01:46,180
‫to the value that was inputted.

35
00:01:46,180 --> 00:01:50,330
‫So in this case, the price discount that the user specified.

36
00:01:50,330 --> 00:01:53,773
‫So that's what I call the value, val for short.

37
00:01:55,340 --> 00:01:57,550
‫Remember that we need to return either

38
00:01:57,550 --> 00:01:59,873
‫true or false from this validator.

39
00:02:04,090 --> 00:02:05,760
‫When do we want to return false,

40
00:02:05,760 --> 00:02:08,230
‫and when do we want to return true?

41
00:02:08,230 --> 00:02:11,210
‫Well, we want an error when the price discount

42
00:02:11,210 --> 00:02:13,553
‫is greater or equal than the price.

43
00:02:14,430 --> 00:02:17,000
‫And so basically what we want to return here

44
00:02:17,000 --> 00:02:19,800
‫is the test of testing

45
00:02:19,800 --> 00:02:23,493
‫if the value is less than this.price.

46
00:02:26,050 --> 00:02:30,210
‫All right, so let's say that the price discount

47
00:02:30,210 --> 00:02:33,693
‫is 100 and that the real price is 200.

48
00:02:35,090 --> 00:02:39,080
‫100 is less than 200, true and so we have no error.

49
00:02:39,080 --> 00:02:42,110
‫And that makes sense because that's exactly what we want.

50
00:02:42,110 --> 00:02:44,990
‫The price discount should always be lower.

51
00:02:44,990 --> 00:02:49,000
‫On the other hand, if the discount is 250,

52
00:02:49,000 --> 00:02:50,970
‫then this turns out to be false.

53
00:02:50,970 --> 00:02:54,623
‫And then false, remember, will trigger a validation error.

54
00:02:57,980 --> 00:02:59,530
‫Let's now test it out actually.

55
00:03:01,890 --> 00:03:02,723
‫Price

56
00:03:03,877 --> 00:03:06,800
‫(keyboard clacking)

57
00:03:06,800 --> 00:03:07,973
‫and price discount.

58
00:03:09,220 --> 00:03:12,000
‫And let's use the values that we used before

59
00:03:13,870 --> 00:03:17,133
‫and I also need to change the name here.

60
00:03:18,660 --> 00:03:22,990
‫Okay, so right now our discount is greater than the price

61
00:03:22,990 --> 00:03:24,833
‫and so we should get our error.

62
00:03:26,440 --> 00:03:30,560
‫Okay and indeed, we have a validation error.

63
00:03:30,560 --> 00:03:33,850
‫So failed for path price discount.

64
00:03:33,850 --> 00:03:37,020
‫Now, we do not have any custom message here

65
00:03:37,020 --> 00:03:39,113
‫and so let's quickly fix that.

66
00:03:40,230 --> 00:03:43,580
‫All right and the way we do that is in a very similar way

67
00:03:43,580 --> 00:03:45,650
‫as we did with the enum.

68
00:03:47,750 --> 00:03:50,510
‫So we need to actually specify another object

69
00:03:50,510 --> 00:03:52,313
‫and then set the message property.

70
00:03:55,830 --> 00:03:56,663
‫Validate

71
00:03:59,320 --> 00:04:00,940
‫should be an object

72
00:04:00,940 --> 00:04:03,280
‫and then we have our message in there

73
00:04:04,370 --> 00:04:06,510
‫and this function here will live

74
00:04:06,510 --> 00:04:08,597
‫in a property called validator.

75
00:04:15,639 --> 00:04:18,205
‫Okay and our message here will be

76
00:04:18,205 --> 00:04:21,527
‫(keyboard clacking)

77
00:04:21,527 --> 00:04:22,360
‫discount price

78
00:04:23,510 --> 00:04:24,343
‫should be

79
00:04:26,220 --> 00:04:27,693
‫below the regular price.

80
00:04:30,520 --> 00:04:34,840
‫Here we need a comma and so now we're good.

81
00:04:34,840 --> 00:04:38,480
‫And actually, one very nice trick is that this message here

82
00:04:38,480 --> 00:04:41,003
‫also has access to the value.

83
00:04:42,180 --> 00:04:44,930
‫And this works in kind of a weird way

84
00:04:44,930 --> 00:04:47,520
‫and this really is internal to Mongoose,

85
00:04:47,520 --> 00:04:49,610
‫so this has nothing to do with JavaScript

86
00:04:49,610 --> 00:04:54,283
‫so I can simply use the curly braces here and then value.

87
00:04:56,030 --> 00:04:58,020
‫So this piece here will get access

88
00:04:58,020 --> 00:04:59,900
‫to the value that was inputted,

89
00:04:59,900 --> 00:05:02,973
‫so it has the exact same value as this val variable.

90
00:05:06,150 --> 00:05:07,400
‫So let's test that again

91
00:05:08,720 --> 00:05:10,850
‫and now indeed we get our message

92
00:05:10,850 --> 00:05:15,800
‫and even access to the 250 price that we specified here.

93
00:05:15,800 --> 00:05:19,890
‫Now let's change it to 100 and so now it should work

94
00:05:19,890 --> 00:05:21,920
‫and yeah, it does.

95
00:05:21,920 --> 00:05:23,570
‫So, great.

96
00:05:23,570 --> 00:05:26,290
‫Now there is one very important caveat

97
00:05:26,290 --> 00:05:28,030
‫that we need to notice here

98
00:05:28,030 --> 00:05:30,763
‫and that is that inside a validator function,

99
00:05:30,763 --> 00:05:33,080
‫that this key word is only gonna point

100
00:05:33,080 --> 00:05:34,290
‫to the current document

101
00:05:34,290 --> 00:05:36,573
‫when we are creating a new document.

102
00:05:37,740 --> 00:05:40,653
‫So this function here is not going to work on update.

103
00:05:41,813 --> 00:05:44,143
‫And so that's very important to note.

104
00:05:45,412 --> 00:05:48,230
‫You see, that in Mongoose, there are a couple of caveats

105
00:05:48,230 --> 00:05:50,110
‫that you really need to be aware of

106
00:05:50,110 --> 00:05:51,990
‫when working with it.

107
00:05:51,990 --> 00:05:54,430
‫And I learned all of these by experience

108
00:05:54,430 --> 00:05:57,390
‫and so that's why now I'm able to tell them to you.

109
00:05:57,390 --> 00:06:00,550
‫So I run into an error once with this one

110
00:06:00,550 --> 00:06:02,090
‫and so from that time on,

111
00:06:02,090 --> 00:06:05,220
‫I know that I can only use this kind of validator

112
00:06:05,220 --> 00:06:07,160
‫with a this keyword in there

113
00:06:07,160 --> 00:06:09,730
‫when I'm actually creating new documents.

114
00:06:09,730 --> 00:06:12,143
‫So let me write that down here for you.

115
00:06:12,143 --> 00:06:15,143
‫(keyboard clacking)

116
00:06:25,210 --> 00:06:28,610
‫All right, so I hope that you're kind of taking note

117
00:06:28,610 --> 00:06:32,440
‫of all of these very important small pieces of information

118
00:06:32,440 --> 00:06:34,083
‫that are very important.

119
00:06:34,940 --> 00:06:36,680
‫The same thing down here.

120
00:06:36,680 --> 00:06:38,530
‫Remember that where I told you that

121
00:06:38,530 --> 00:06:42,100
‫this DOCUMENT MIDDLEWARE only really runs for save

122
00:06:42,100 --> 00:06:44,640
‫and create but not for update.

123
00:06:44,640 --> 00:06:46,700
‫And that's one of these other things

124
00:06:46,700 --> 00:06:49,013
‫that are really important to never forget.

125
00:06:51,330 --> 00:06:52,860
‫Now in this specific case here,

126
00:06:52,860 --> 00:06:55,870
‫there are actually ways around fixing this

127
00:06:55,870 --> 00:06:58,903
‫but they're very complicated and not really worth pursuing.

128
00:07:00,070 --> 00:07:02,810
‫And we could of course also write validator functions

129
00:07:02,810 --> 00:07:05,370
‫that do not rely on a this variable.

130
00:07:05,370 --> 00:07:08,000
‫So in this case, we only need it because we are comparing

131
00:07:08,000 --> 00:07:11,363
‫one value with the value of another field.

132
00:07:14,150 --> 00:07:17,370
‫This is a custom validator that we can use in Mongoose

133
00:07:17,370 --> 00:07:20,180
‫and that we did actually write ourself.

134
00:07:20,180 --> 00:07:23,170
‫But also, there are a couple of libraries on npm

135
00:07:23,170 --> 00:07:26,300
‫for data validation that we can simply plug in here

136
00:07:26,300 --> 00:07:30,183
‫as custom validators that we do not have to write ourselves.

137
00:07:31,394 --> 00:07:34,370
‫And the most popular library is called validator

138
00:07:34,370 --> 00:07:36,883
‫and so let's actually take a look at that one.

139
00:07:41,490 --> 00:07:44,520
‫Validator and then I'm searching for GitHub

140
00:07:44,520 --> 00:07:48,620
‫because usually all of these libraries are always on GitHub.

141
00:07:48,620 --> 00:07:51,300
‫And the documentation is also gonna be there

142
00:07:52,210 --> 00:07:53,660
‫and so here you see

143
00:07:55,060 --> 00:07:56,330
‫that validator

144
00:07:56,330 --> 00:07:59,773
‫is a library of string validators and sanitizers.

145
00:08:01,155 --> 00:08:05,310
‫You also see that it's quite popular with 13,00 stars

146
00:08:05,310 --> 00:08:06,500
‫and so

147
00:08:06,500 --> 00:08:08,033
‫that's very good.

148
00:08:09,880 --> 00:08:11,830
‫We also see this library validates

149
00:08:11,830 --> 00:08:13,683
‫and sanitize only strings.

150
00:08:15,562 --> 00:08:18,280
‫Here is then all of the stuff how we install it

151
00:08:18,280 --> 00:08:21,070
‫and how we use it but that's kind of simple.

152
00:08:21,070 --> 00:08:22,655
‫We already know that.

153
00:08:22,655 --> 00:08:24,650
‫But what I want to show you is the list

154
00:08:24,650 --> 00:08:26,990
‫of all the available validators.

155
00:08:26,990 --> 00:08:29,490
‫For example, we have isAlpha,

156
00:08:29,490 --> 00:08:32,900
‫which is gonna check if the string contains only letters.

157
00:08:32,900 --> 00:08:36,140
‫We have Alphanumeric so only letters and numbers

158
00:08:36,980 --> 00:08:38,910
‫and we really have a lot of stuff here.

159
00:08:38,910 --> 00:08:40,820
‫So check if a string is boolian,

160
00:08:40,820 --> 00:08:43,870
‫or check if the string is a credit card,

161
00:08:43,870 --> 00:08:46,160
‫so valid credit card number.

162
00:08:46,160 --> 00:08:48,700
‫Or if it's a currency

163
00:08:48,700 --> 00:08:52,860
‫or you see really all kinds of different tests.

164
00:08:52,860 --> 00:08:56,783
‫For example an ISBN, so for checking book numbers.

165
00:08:59,020 --> 00:09:02,683
‫To test if it's an integer or if the string is lowercase.

166
00:09:03,740 --> 00:09:07,050
‫And so you see, whenever you need some data validation

167
00:09:07,050 --> 00:09:08,970
‫you can grab one of these libraries

168
00:09:08,970 --> 00:09:11,993
‫and simply plug them into your Mongoose validators.

169
00:09:13,650 --> 00:09:15,560
‫Now many of the things that are here

170
00:09:15,560 --> 00:09:17,800
‫are actually already built into Mongoose

171
00:09:17,800 --> 00:09:20,810
‫and so we don't need all of them, okay,

172
00:09:20,810 --> 00:09:23,010
‫but there is one very specific,

173
00:09:23,010 --> 00:09:25,880
‫which I want to use, which is isAlpha.

174
00:09:25,880 --> 00:09:30,290
‫So I want to check if the tour name only contains letters.

175
00:09:30,290 --> 00:09:32,200
‫And so for that I can use this function

176
00:09:32,200 --> 00:09:33,963
‫from the validator library.

177
00:09:35,940 --> 00:09:36,773
‫Let's go back

178
00:09:38,804 --> 00:09:40,000
‫and start by installing

179
00:09:41,660 --> 00:09:42,493
‫npm

180
00:09:42,493 --> 00:09:43,877
‫i

181
00:09:43,877 --> 00:09:45,270
‫(keyboard clacking)

182
00:09:45,270 --> 00:09:46,163
‫validator.

183
00:09:52,614 --> 00:09:53,793
‫That was successful.

184
00:09:56,481 --> 00:09:57,931
‫Then I need to import it here

185
00:10:01,430 --> 00:10:05,363
‫and so now we're good to go to actually use it here.

186
00:10:07,380 --> 00:10:08,530
‫I'm gonna use it here

187
00:10:08,530 --> 00:10:10,790
‫and again, I use the validate property

188
00:10:12,510 --> 00:10:13,900
‫and now all I need to do

189
00:10:13,900 --> 00:10:16,253
‫is to really plug in the function here.

190
00:10:18,470 --> 00:10:21,350
‫And in validator, it works like this,

191
00:10:21,350 --> 00:10:23,530
‫where validator is an object

192
00:10:23,530 --> 00:10:26,330
‫and on there we have then all these methods.

193
00:10:26,330 --> 00:10:27,560
‫Validator

194
00:10:27,560 --> 00:10:28,393
‫is

195
00:10:30,240 --> 00:10:31,073
‫Alpha,

196
00:10:31,073 --> 00:10:32,490
‫so that's the one that we just choose

197
00:10:32,490 --> 00:10:33,783
‫from the documentation.

198
00:10:34,936 --> 00:10:36,090
‫And that's actually it.

199
00:10:36,090 --> 00:10:37,760
‫So we don't call it here.

200
00:10:37,760 --> 00:10:39,900
‫We basically just specify

201
00:10:39,900 --> 00:10:42,780
‫that this is a function that should be used.

202
00:10:42,780 --> 00:10:45,920
‫Just like our own one, like our own validator,

203
00:10:45,920 --> 00:10:46,830
‫we didn't call it.

204
00:10:46,830 --> 00:10:48,870
‫We simply put this callback function here

205
00:10:48,870 --> 00:10:49,970
‫that it's gonna be called

206
00:10:49,970 --> 00:10:52,153
‫as soon as the data should be validated.

207
00:10:54,527 --> 00:10:56,090
‫And so here, it's the same.

208
00:10:56,090 --> 00:10:58,490
‫Now, if we wanna specify an error message,

209
00:10:58,490 --> 00:11:00,550
‫it works just like up here.

210
00:11:00,550 --> 00:11:04,180
‫We can specify an array and then the error message

211
00:11:04,180 --> 00:11:05,850
‫after the callback function.

212
00:11:05,850 --> 00:11:07,883
‫And we could have done it down here.

213
00:11:09,120 --> 00:11:11,000
‫So here we did it differently.

214
00:11:11,000 --> 00:11:13,230
‫Here we then created this new object

215
00:11:13,230 --> 00:11:16,010
‫with validator in there and the message,

216
00:11:16,010 --> 00:11:18,220
‫but we could've done it with an array as well,

217
00:11:18,220 --> 00:11:20,183
‫but that would've looked weird.

218
00:11:21,130 --> 00:11:23,830
‫But up here, since the function is so small,

219
00:11:23,830 --> 00:11:26,540
‫so this is so small, we can simply put it here

220
00:11:26,540 --> 00:11:29,040
‫and then as a second argument in the array

221
00:11:29,040 --> 00:11:30,463
‫add the error message.

222
00:11:32,640 --> 00:11:35,110
‫Tour name must only contain

223
00:11:35,973 --> 00:11:39,310
‫(keyboard clacking)
‫characters.

224
00:11:39,310 --> 00:11:41,053
‫Great, check that out.

225
00:11:42,320 --> 00:11:47,053
‫Back in Postman here, let's get rid of our price discount.

226
00:11:48,990 --> 00:11:51,290
‫And let's add some number here.

227
00:11:51,290 --> 00:11:53,140
‫And so that should then fail the test

228
00:11:54,450 --> 00:11:57,433
‫and indeed, the name must only contain characters.

229
00:11:59,760 --> 00:12:01,430
‫Let's get rid of that.

230
00:12:01,430 --> 00:12:02,760
‫We can also not use this name.

231
00:12:02,760 --> 00:12:05,040
‫We already used it before,

232
00:12:05,040 --> 00:12:08,500
‫so that can be write out too here with characters

233
00:12:10,060 --> 00:12:13,503
‫and we still get this error here.

234
00:12:15,470 --> 00:12:18,830
‫Well, that's probably because of the spaces.

235
00:12:18,830 --> 00:12:20,970
‫So let's just get rid of the spaces,

236
00:12:20,970 --> 00:12:23,900
‫which of course is not gonna be real useful

237
00:12:23,900 --> 00:12:25,910
‫and indeed, now it works.

238
00:12:25,910 --> 00:12:27,900
‫So the problem was the spaces,

239
00:12:27,900 --> 00:12:30,483
‫but obviously we want to keep the spaces here.

240
00:12:32,650 --> 00:12:36,400
‫In fact, this validation error is not really useful

241
00:12:36,400 --> 00:12:37,993
‫and so I will get rid of it.

242
00:12:39,340 --> 00:12:42,430
‫Consider that this here was only to demonstrate

243
00:12:42,430 --> 00:12:45,030
‫that we can use an external library like this

244
00:12:45,030 --> 00:12:46,880
‫to perform validation.

245
00:12:46,880 --> 00:12:49,670
‫And actually, we will still use this library a bit later

246
00:12:49,670 --> 00:12:53,390
‫when we check if the user email is actually valid.

247
00:12:53,390 --> 00:12:54,860
‫So that's another nice function

248
00:12:54,860 --> 00:12:56,873
‫that is included in this library.

249
00:12:58,788 --> 00:13:00,290
‫So again, this is how it works.

250
00:13:00,290 --> 00:13:02,270
‫Not really useful in this case,

251
00:13:02,270 --> 00:13:04,050
‫so if we really wanted to test

252
00:13:04,050 --> 00:13:08,160
‫if the string only contains letters and spaces

253
00:13:08,160 --> 00:13:09,700
‫it would probably be simpler

254
00:13:09,700 --> 00:13:12,250
‫to simply use a regular expression

255
00:13:12,250 --> 00:13:14,153
‫to test for that kind of pattern.

256
00:13:15,210 --> 00:13:16,500
‫But I'm not gonna do that here

257
00:13:16,500 --> 00:13:18,410
‫because this lecture was more about

258
00:13:18,410 --> 00:13:20,230
‫these custom validators.

259
00:13:20,230 --> 00:13:23,810
‫Anyway, with this lecture, we are now ready

260
00:13:23,810 --> 00:13:25,863
‫with the introduction to Mongoose.

261
00:13:27,370 --> 00:13:29,500
‫Now as you can imagine, there is of course

262
00:13:29,500 --> 00:13:31,530
‫still a lot to learn about Mongoose

263
00:13:31,530 --> 00:13:34,540
‫and in fact, we have a advanced Mongoose section

264
00:13:34,540 --> 00:13:36,010
‫a bit later in the course

265
00:13:36,010 --> 00:13:38,010
‫and of course also in the other sections,

266
00:13:38,010 --> 00:13:39,710
‫you will keep learning more and more

267
00:13:39,710 --> 00:13:41,390
‫about how to use Mongoose

268
00:13:41,390 --> 00:13:43,183
‫in a real professional way.

269
00:13:44,380 --> 00:13:47,070
‫You have already learned so much up until this point,

270
00:13:47,070 --> 00:13:50,630
‫so huge congratulations for making it this far

271
00:13:50,630 --> 00:13:53,680
‫and it's great to see that you're still with me here.

272
00:13:53,680 --> 00:13:56,913
‫So great job and I hope to see you soon.

