1 00:00:01,300 --> 00:00:02,640 So you already learnt 2 00:00:02,640 --> 00:00:05,930 how to create new documents in the database. 3 00:00:05,930 --> 00:00:07,610 But in this lecture I'm going to show you 4 00:00:07,610 --> 00:00:10,940 an easier and even better way of doing so, 5 00:00:10,940 --> 00:00:13,933 as we implement our create tour handler. 6 00:00:15,620 --> 00:00:17,620 So at this point our API 7 00:00:17,620 --> 00:00:19,690 basically doesn't do anything anymore. 8 00:00:19,690 --> 00:00:21,140 It doesn't work anymore 9 00:00:21,140 --> 00:00:23,850 because basically we deleted all the functionality 10 00:00:23,850 --> 00:00:25,760 that we had in the last video. 11 00:00:25,760 --> 00:00:28,740 And we did so, so that over the next couple of lectures 12 00:00:28,740 --> 00:00:32,230 we can rebuild it using a real database. 13 00:00:32,230 --> 00:00:36,810 Okay, so basically finally building our real API. 14 00:00:36,810 --> 00:00:38,500 And we're gonna start by implementing 15 00:00:38,500 --> 00:00:39,957 the createTour function. 16 00:00:39,957 --> 00:00:42,260 But just remember the handler function 17 00:00:42,260 --> 00:00:45,300 that is called as soon as there is a post request 18 00:00:45,300 --> 00:00:47,420 to the tours route. 19 00:00:47,420 --> 00:00:50,460 So that's what we have here in tourRoutes. 20 00:00:51,300 --> 00:00:53,320 So let's put that here. 21 00:00:53,320 --> 00:00:56,930 So what I just said is this. 22 00:00:56,930 --> 00:00:59,940 So we have this checkBody here. 23 00:00:59,940 --> 00:01:01,450 Which actually is something 24 00:01:01,450 --> 00:01:03,663 that we will be able to delete as well. 25 00:01:04,920 --> 00:01:06,313 So where is that, actually? 26 00:01:07,583 --> 00:01:09,120 checkBody 27 00:01:09,120 --> 00:01:12,750 alright, so this is yet another of these functions 28 00:01:12,750 --> 00:01:14,290 that we really don't need anymore. 29 00:01:14,290 --> 00:01:17,180 Because this was basically to validate the body. 30 00:01:17,180 --> 00:01:22,060 So to see if it had the name or the price property in them. 31 00:01:22,060 --> 00:01:22,900 Right? 32 00:01:22,900 --> 00:01:24,690 But now our mongoose model 33 00:01:24,690 --> 00:01:26,650 is actually gonna take care of that. 34 00:01:26,650 --> 00:01:28,830 And so again, this here was nice 35 00:01:28,830 --> 00:01:31,900 to actually show us how middle-ware works 36 00:01:31,900 --> 00:01:34,143 but now we can get rid of it. 37 00:01:35,490 --> 00:01:39,410 Okay, and so I'm gonna delete it from here as well. 38 00:01:39,410 --> 00:01:40,393 Give it a new save. 39 00:01:41,474 --> 00:01:43,400 And it's now back to working. 40 00:01:43,400 --> 00:01:45,660 Anyway the function that we're creating now 41 00:01:45,660 --> 00:01:48,000 is this createTour function. 42 00:01:48,000 --> 00:01:50,050 Where just the one data is going to get called 43 00:01:50,050 --> 00:01:54,690 as soon as someone hits the tour route with a post request. 44 00:01:54,690 --> 00:01:57,030 Okay, so just to recap that 45 00:01:57,030 --> 00:01:59,150 because I know that it can be a bit confusing 46 00:01:59,150 --> 00:02:02,190 with these different files and different folders 47 00:02:02,190 --> 00:02:03,980 and different functions. 48 00:02:03,980 --> 00:02:05,430 But it's also really important 49 00:02:05,430 --> 00:02:07,610 that we start organizing our code 50 00:02:07,610 --> 00:02:08,860 right from the beginning. 51 00:02:09,940 --> 00:02:10,900 Okay? 52 00:02:10,900 --> 00:02:14,710 Anyway, we are here in the createTour function. 53 00:02:14,710 --> 00:02:17,200 And so let's now actually create a new tour. 54 00:02:17,200 --> 00:02:19,270 And we're gonna do that based on the data 55 00:02:19,270 --> 00:02:21,290 that comes in from the body. 56 00:02:21,290 --> 00:02:22,640 Remember that? 57 00:02:22,640 --> 00:02:24,980 Now remember how we used to create documents 58 00:02:24,980 --> 00:02:26,363 a couple of lectures ago. 59 00:02:27,470 --> 00:02:29,253 So we did it like this. 60 00:02:30,690 --> 00:02:32,487 For example let's say newTour 61 00:02:33,327 --> 00:02:35,077 then equal to newTour 62 00:02:37,910 --> 00:02:40,014 and then the data in there. 63 00:02:40,014 --> 00:02:44,181 So we did it like this and then that's a new tour. 64 00:02:46,087 --> 00:02:48,504 And then we type newTour.save 65 00:02:50,290 --> 00:02:51,920 and that works kinda fine. 66 00:02:51,920 --> 00:02:54,780 But we can do it in an even easier way. 67 00:02:54,780 --> 00:02:58,010 So instead of doing this we can do 68 00:03:02,220 --> 00:03:05,690 Tour.create and then paste the data in there. 69 00:03:05,690 --> 00:03:08,070 Okay and that will do the exact same thing. 70 00:03:08,070 --> 00:03:10,900 The main difference is that in this version here 71 00:03:10,900 --> 00:03:14,170 we basically call the method directly on the tour 72 00:03:14,170 --> 00:03:17,330 while in this first version we called the method 73 00:03:17,330 --> 00:03:18,970 on the new document. 74 00:03:18,970 --> 00:03:21,560 Okay, and so that is completely different. 75 00:03:21,560 --> 00:03:23,940 So again we had the tour that we created 76 00:03:23,940 --> 00:03:24,920 from the model. 77 00:03:24,920 --> 00:03:27,920 And then on that tour we used the save method. 78 00:03:27,920 --> 00:03:30,720 Because the document has access to this method 79 00:03:30,720 --> 00:03:33,030 and a lot of other methods as well. 80 00:03:33,030 --> 00:03:35,040 But here in the second situation 81 00:03:35,040 --> 00:03:39,373 we call this create method right on the model itself, okay? 82 00:03:40,560 --> 00:03:45,463 Now remember how this save method here returned a promise. 83 00:03:46,480 --> 00:03:49,670 And so this create here does return a promise as well. 84 00:03:49,670 --> 00:03:52,630 And so in order to get access to the file document 85 00:03:52,630 --> 00:03:54,690 as it was created in the database, 86 00:03:54,690 --> 00:03:58,880 we would then to have used .then okay? 87 00:03:58,880 --> 00:04:01,810 But instead of using promises like this, 88 00:04:01,810 --> 00:04:03,920 I'm gonna start using async await. 89 00:04:03,920 --> 00:04:04,860 Alright. 90 00:04:04,860 --> 00:04:07,960 So this function here should be an async function. 91 00:04:07,960 --> 00:04:09,900 So all we need to do 92 00:04:09,900 --> 00:04:12,250 is to write async right here. 93 00:04:12,250 --> 00:04:15,760 So we have async and so we can now await the result 94 00:04:15,760 --> 00:04:16,903 of this promise here. 95 00:04:18,255 --> 00:04:21,010 So I hope you are familiar with this. 96 00:04:21,010 --> 00:04:23,030 And I actually have a section in this course 97 00:04:23,030 --> 00:04:25,890 that deals with exactly this kind of stuff. 98 00:04:25,890 --> 00:04:27,490 So if you didn't watch that section 99 00:04:27,490 --> 00:04:30,920 but are still not 100% familiar with async await 100 00:04:30,920 --> 00:04:33,280 then please go ahead and watch that section 101 00:04:33,280 --> 00:04:36,040 so that you really understand what's going on here. 102 00:04:36,040 --> 00:04:39,270 Okay, so instead of using this then here 103 00:04:39,270 --> 00:04:40,960 I'm gonna use async await 104 00:04:40,960 --> 00:04:43,790 and then save the result value of this promise 105 00:04:43,790 --> 00:04:45,413 in the new tour variable. 106 00:04:49,220 --> 00:04:52,020 Okay, now the final piece of the puzzle here 107 00:04:52,020 --> 00:04:56,410 is to of course pass some real data into this create method. 108 00:04:56,410 --> 00:04:58,410 And so instead of this empty object 109 00:04:58,410 --> 00:05:01,310 we're gonna pass in the request body 110 00:05:01,310 --> 00:05:05,020 so req.body and so that's the data 111 00:05:05,020 --> 00:05:08,010 that comes with the post request, right? 112 00:05:08,010 --> 00:05:09,290 Now just one more time, 113 00:05:09,290 --> 00:05:12,600 just to make sure that everything is clear to you. 114 00:05:12,600 --> 00:05:15,920 Okay so we can use the tour model directly 115 00:05:15,920 --> 00:05:18,340 and call the create method on it. 116 00:05:18,340 --> 00:05:20,630 Then into that function we pass the data 117 00:05:20,630 --> 00:05:23,600 that we want to store in the database as a new tour. 118 00:05:23,600 --> 00:05:26,810 And that data comes from the post body, right? 119 00:05:26,810 --> 00:05:30,730 And so that's stored inside of request dot body. 120 00:05:30,730 --> 00:05:32,460 So this variable here. 121 00:05:32,460 --> 00:05:35,503 Now this method here will then return a promise. 122 00:05:36,473 --> 00:05:38,850 And we await that promise using async await 123 00:05:38,850 --> 00:05:42,000 and then store that result into the newTour variable 124 00:05:42,000 --> 00:05:44,050 which will be the newly created document 125 00:05:44,050 --> 00:05:48,083 already with the ID and everything, okay? 126 00:05:49,700 --> 00:05:51,130 So I'm gonna keep this code here 127 00:05:51,130 --> 00:05:53,160 just as a reference. 128 00:05:53,160 --> 00:05:57,210 And for now let's get this piece of data here back. 129 00:05:57,210 --> 00:05:58,363 Piece of code actually. 130 00:05:59,250 --> 00:06:00,720 Give it a save. 131 00:06:00,720 --> 00:06:03,950 And now we get this ES lint error. 132 00:06:03,950 --> 00:06:05,360 So let's take a look at that 133 00:06:05,360 --> 00:06:07,300 just put our mouse on here. 134 00:06:07,300 --> 00:06:10,500 And it tells us that async functions are not supported 135 00:06:10,500 --> 00:06:13,230 until this node 7.6 136 00:06:13,230 --> 00:06:16,140 and so this ES lint error comes from that node plugin 137 00:06:16,140 --> 00:06:17,320 that we actually installed. 138 00:06:17,320 --> 00:06:18,450 So you can see that here. 139 00:06:18,450 --> 00:06:21,410 Alright, so what we're gonna to do fix this 140 00:06:21,410 --> 00:06:23,920 is to simple go to package.json 141 00:06:23,920 --> 00:06:25,600 and in here you find the node version 142 00:06:25,600 --> 00:06:27,180 that we are actually using. 143 00:06:27,180 --> 00:06:28,383 So that's very simple. 144 00:06:30,880 --> 00:06:33,790 We just need to specify the engines property 145 00:06:33,790 --> 00:06:36,673 here in our json document. 146 00:06:39,070 --> 00:06:43,830 And set node to greater or equal 147 00:06:44,850 --> 00:06:47,230 than 10. 148 00:06:47,230 --> 00:06:48,850 Okay, and that's because in this course 149 00:06:48,850 --> 00:06:51,053 we are using at least node ten. 150 00:06:52,636 --> 00:06:56,490 So 7.6 would be enough in order to make that error disappear 151 00:06:56,490 --> 00:06:58,610 but of course we specify the real version 152 00:06:58,610 --> 00:06:59,890 that we're actually using. 153 00:06:59,890 --> 00:07:01,690 So we give this one a save. 154 00:07:01,690 --> 00:07:03,010 Close that up. 155 00:07:03,010 --> 00:07:06,500 And so now our error here is actually gone. 156 00:07:06,500 --> 00:07:09,560 Now just one more step before we can actually try this out 157 00:07:09,560 --> 00:07:11,330 in our Postman app. 158 00:07:11,330 --> 00:07:14,210 And that is that we actually need to handle errors. 159 00:07:14,210 --> 00:07:17,860 Okay, and so keep in mind that with async await 160 00:07:17,860 --> 00:07:22,650 we need to test for errors using the try catch syntax. 161 00:07:22,650 --> 00:07:26,003 So we write a try block. 162 00:07:27,160 --> 00:07:28,760 Then wrap all our code in there. 163 00:07:32,065 --> 00:07:33,615 And then finally a catch block. 164 00:07:34,920 --> 00:07:39,190 Which as we already know has access to the error object. 165 00:07:39,190 --> 00:07:41,410 And now what do we actually put here? 166 00:07:41,410 --> 00:07:42,940 Well we need to think about 167 00:07:42,940 --> 00:07:45,410 when exactly an error can happen. 168 00:07:45,410 --> 00:07:47,790 So remember like two lectures ago 169 00:07:47,790 --> 00:07:50,410 when we were creating our first documents. 170 00:07:50,410 --> 00:07:51,820 We got an error back then 171 00:07:51,820 --> 00:07:53,870 when we tried to create a document 172 00:07:53,870 --> 00:07:56,600 without one of the required fields, right? 173 00:07:56,600 --> 00:07:58,700 And so that was a validation error. 174 00:07:58,700 --> 00:08:02,370 And it's one of the errors that would get catched here. 175 00:08:02,370 --> 00:08:05,290 Okay because if we tried to create a document 176 00:08:05,290 --> 00:08:07,640 let's say without one of the required fields 177 00:08:07,640 --> 00:08:09,900 then this promise that is created here 178 00:08:09,900 --> 00:08:12,430 would be rejected, okay? 179 00:08:12,430 --> 00:08:15,000 And so if we have a rejected promise here 180 00:08:15,000 --> 00:08:17,740 then it will enter the catch block. 181 00:08:17,740 --> 00:08:20,870 And so therefore, basically in this catch block here 182 00:08:20,870 --> 00:08:23,050 we want to send back a response 183 00:08:23,050 --> 00:08:25,580 saying that there was an error. 184 00:08:25,580 --> 00:08:30,580 Alright so res.status here again 185 00:08:30,670 --> 00:08:33,483 and 400 which stands for bad request. 186 00:08:35,967 --> 00:08:36,980 .json 187 00:08:37,950 --> 00:08:40,290 and now something very similar to this one 188 00:08:40,290 --> 00:08:43,310 but its status and that's fail 189 00:08:44,270 --> 00:08:48,050 and then instead of data here we send a message 190 00:08:48,970 --> 00:08:51,520 and for now lets just set the message to the error. 191 00:08:52,560 --> 00:08:53,393 Alright. 192 00:08:54,800 --> 00:08:59,260 And let's now finally get back to our Postman application 193 00:08:59,260 --> 00:09:01,643 and give this a try. 194 00:09:01,643 --> 00:09:03,990 Okay, so create this one 195 00:09:03,990 --> 00:09:06,170 and let's now create a new tour. 196 00:09:06,170 --> 00:09:07,790 So right now here we have 197 00:09:07,790 --> 00:09:11,370 the name duration difficulty and price 198 00:09:11,370 --> 00:09:13,860 and so let's actually also add the rating 199 00:09:15,400 --> 00:09:18,040 and that needs to be in double quotes 200 00:09:21,050 --> 00:09:21,883 4.7. 201 00:09:22,900 --> 00:09:25,570 Alright, and now comes the moment. 202 00:09:25,570 --> 00:09:29,330 Send and indeed here we go. 203 00:09:29,330 --> 00:09:32,170 So this is the tour 204 00:09:32,170 --> 00:09:33,430 that we just created. 205 00:09:33,430 --> 00:09:34,520 We have our rating. 206 00:09:34,520 --> 00:09:36,950 We have our name and we have our price. 207 00:09:36,950 --> 00:09:39,780 And of course the automatically created ID. 208 00:09:39,780 --> 00:09:40,890 Now you might notice 209 00:09:40,890 --> 00:09:44,360 that we have no difficulty and no price. 210 00:09:44,360 --> 00:09:46,870 Well why do you think that is? 211 00:09:46,870 --> 00:09:48,920 Well that's because these two fields 212 00:09:48,920 --> 00:09:51,030 are actually not in our schema 213 00:09:51,030 --> 00:09:54,240 and so therefore they are not put in the database. 214 00:09:54,240 --> 00:09:56,730 So everything else that is not in our schema 215 00:09:56,730 --> 00:09:57,840 is simply ignored. 216 00:09:57,840 --> 00:10:01,800 So that is the power of our schema, alright? 217 00:10:01,800 --> 00:10:05,210 Great, now let's actually try to send this again 218 00:10:05,210 --> 00:10:08,113 and so that should give us an error, right? 219 00:10:08,950 --> 00:10:10,650 And indeed there we go. 220 00:10:10,650 --> 00:10:13,340 We have our 400 bad request. 221 00:10:13,340 --> 00:10:15,200 And we have this message 222 00:10:15,200 --> 00:10:17,810 which is the complete error that we got. 223 00:10:17,810 --> 00:10:21,330 And so here we see that the error message is duplicate key. 224 00:10:21,330 --> 00:10:24,510 And so that's because we already have the Test Tour 2. 225 00:10:24,510 --> 00:10:26,563 And so it could not create another one. 226 00:10:29,330 --> 00:10:33,960 So let's just create another one here like Jonas Tour. 227 00:10:33,960 --> 00:10:35,933 It doesn't really matter, okay? 228 00:10:36,850 --> 00:10:39,083 I just wanna create it, 229 00:10:39,940 --> 00:10:42,490 first without any of this 230 00:10:42,490 --> 00:10:45,030 just to see if we get another error. 231 00:10:45,030 --> 00:10:48,070 And indeed we get some more errors here. 232 00:10:48,070 --> 00:10:50,300 This time saying that 233 00:10:50,300 --> 00:10:51,870 that the tour validation failed 234 00:10:51,870 --> 00:10:54,053 because a tour must have a price. 235 00:10:54,980 --> 00:10:57,170 Okay, so you see that right now we have 236 00:10:57,170 --> 00:11:00,090 this kind of weird error structure here. 237 00:11:00,090 --> 00:11:04,650 So Mongo DB gives back this huge complete error object. 238 00:11:04,650 --> 00:11:07,100 And later on we're actually gonna take care of that. 239 00:11:07,100 --> 00:11:10,720 So we will have an entire section on error handling alone. 240 00:11:10,720 --> 00:11:14,420 And by then we will create some more meaningful errors. 241 00:11:14,420 --> 00:11:18,080 Okay, for now let's just replace this error object 242 00:11:18,080 --> 00:11:20,490 with some normal string here. 243 00:11:20,490 --> 00:11:25,440 So let's say invalid data sent. 244 00:11:25,440 --> 00:11:27,950 Okay, so don't do something like this 245 00:11:27,950 --> 00:11:30,350 in a real production application 246 00:11:30,350 --> 00:11:32,930 but again we're gonna have some real error handling 247 00:11:32,930 --> 00:11:35,430 a bit later which is gonna take care of that. 248 00:11:35,430 --> 00:11:39,360 Okay, so displaying meaningful errors to the client. 249 00:11:39,360 --> 00:11:40,750 So let's just go back here 250 00:11:41,610 --> 00:11:43,040 send it again. 251 00:11:43,040 --> 00:11:45,950 And so now we get this normal string here. 252 00:11:45,950 --> 00:11:50,510 So let's just create the price here. 253 00:11:50,510 --> 00:11:53,520 Let's set it to 567 254 00:11:54,490 --> 00:11:55,700 then send it. 255 00:11:55,700 --> 00:11:56,860 And so now you will see 256 00:11:56,860 --> 00:11:59,813 that our default rating here is actually still working. 257 00:12:01,800 --> 00:12:05,810 Let's now figure all of this out in compass as well. 258 00:12:05,810 --> 00:12:09,860 And indeed we get our four tours in the database. 259 00:12:09,860 --> 00:12:12,210 So all these weird tests 260 00:12:12,210 --> 00:12:14,960 that we've been doing up until this point. 261 00:12:14,960 --> 00:12:19,140 So let's just go ahead and delete these last two. 262 00:12:19,140 --> 00:12:21,123 That were really just for testing. 263 00:12:24,500 --> 00:12:26,130 Alright. 264 00:12:26,130 --> 00:12:28,773 So something went wrong here I guess. 265 00:12:30,130 --> 00:12:32,782 Okay, now we're back to these two. 266 00:12:32,782 --> 00:12:34,610 Let's now just create the third one 267 00:12:34,610 --> 00:12:36,760 that we actually had before in the last section. 268 00:12:36,760 --> 00:12:38,763 Which is the Snow Adventurer. 269 00:12:42,490 --> 00:12:43,630 So the Snow 270 00:12:45,800 --> 00:12:47,080 Adventurer. 271 00:12:47,080 --> 00:12:48,280 The price was ... 272 00:12:48,280 --> 00:12:49,790 I'm not sure anymore 273 00:12:49,790 --> 00:12:51,973 like 697 maybe. 274 00:12:54,410 --> 00:12:57,870 And the rating is like six 275 00:12:57,870 --> 00:12:59,963 or actually 4.8. 276 00:13:01,360 --> 00:13:02,800 Sent that guy. 277 00:13:02,800 --> 00:13:04,600 And so indeed here we go. 278 00:13:04,600 --> 00:13:05,810 Great. 279 00:13:05,810 --> 00:13:09,050 Just to quickly recap our createTour function. 280 00:13:09,050 --> 00:13:10,740 So we have a try catch here 281 00:13:10,740 --> 00:13:13,833 because we're actually using an async await function here. 282 00:13:14,859 --> 00:13:16,100 Right, so we use async await 283 00:13:16,100 --> 00:13:18,910 because this tour.create returns a promise 284 00:13:18,910 --> 00:13:21,500 that we're awaiting so that we can then store 285 00:13:21,500 --> 00:13:23,530 the newly created tour document 286 00:13:23,530 --> 00:13:25,340 inside of this variable 287 00:13:25,340 --> 00:13:27,277 and then send it along with the response 288 00:13:27,277 --> 00:13:30,280 to the client down here. 289 00:13:30,280 --> 00:13:32,600 Okay but in case there is an error, 290 00:13:32,600 --> 00:13:34,850 like a validation error for example 291 00:13:34,850 --> 00:13:37,120 then that error is gonna be catched 292 00:13:37,120 --> 00:13:39,700 and we send something else back to the client 293 00:13:39,700 --> 00:13:41,900 with this error message. 294 00:13:41,900 --> 00:13:44,890 So this is how we create documents using mongoose. 295 00:13:44,890 --> 00:13:47,963 Next up we're gonna talk about reading documents.