‫So you already learnt
‫how to create new documents in the database.
‫But in this lecture I'm going to show you
‫an easier and even better way of doing so,
‫as we implement our create tour handler.
‫So at this point our API
‫basically doesn't do anything anymore.
‫It doesn't work anymore
‫because basically we deleted all the functionality
‫that we had in the last video.
‫And we did so, so that over the next couple of lectures
‫we can rebuild it using a real database.
‫Okay, so basically finally building our real API.
‫And we're gonna start by implementing
‫the createTour function.
‫But just remember the handler function
‫that is called as soon as there is a post request
‫to the tours route.
‫So that's what we have here in tourRoutes.
‫So let's put that here.
‫So what I just said is this.
‫So we have this checkBody here.
‫Which actually is something
‫that we will be able to delete as well.
‫So where is that, actually?
‫checkBody
‫alright, so this is yet another of these functions
‫that we really don't need anymore.
‫Because this was basically to validate the body.
‫So to see if it had the name or the price property in them.
‫Right?
‫But now our mongoose model
‫is actually gonna take care of that.
‫And so again, this here was nice
‫to actually show us how middle-ware works
‫but now we can get rid of it.
‫Okay, and so I'm gonna delete it from here as well.
‫Give it a new save.
‫And it's now back to working.
‫Anyway the function that we're creating now
‫is this createTour function.
‫Where just the one data is going to get called
‫as soon as someone hits the tour route with a post request.
‫Okay, so just to recap that
‫because I know that it can be a bit confusing
‫with these different files and different folders
‫and different functions.
‫But it's also really important
‫that we start organizing our code
‫right from the beginning.
‫Okay?
‫Anyway, we are here in the createTour function.
‫And so let's now actually create a new tour.
‫And we're gonna do that based on the data
‫that comes in from the body.
‫Remember that?
‫Now remember how we used to create documents
‫a couple of lectures ago.
‫So we did it like this.
‫For example let's say newTour
‫then equal to newTour
‫and then the data in there.
‫So we did it like this and then that's a new tour.
‫And then we type newTour.save
‫and that works kinda fine.
‫But we can do it in an even easier way.
‫So instead of doing this we can do
‫Tour.create and then paste the data in there.
‫Okay and that will do the exact same thing.
‫The main difference is that in this version here
‫we basically call the method directly on the tour
‫while in this first version we called the method
‫on the new document.
‫Okay, and so that is completely different.
‫So again we had the tour that we created
‫from the model.
‫And then on that tour we used the save method.
‫Because the document has access to this method
‫and a lot of other methods as well.
‫But here in the second situation
‫we call this create method right on the model itself, okay?
‫Now remember how this save method here returned a promise.
‫And so this create here does return a promise as well.
‫And so in order to get access to the file document
‫as it was created in the database,
‫we would then to have used .then okay?
‫But instead of using promises like this,
‫I'm gonna start using async await.
‫Alright.
‫So this function here should be an async function.
‫So all we need to do
‫is to write async right here.
‫So we have async and so we can now await the result
‫of this promise here.
‫So I hope you are familiar with this.
‫And I actually have a section in this course
‫that deals with exactly this kind of stuff.
‫So if you didn't watch that section
‫but are still not 100% familiar with async await
‫then please go ahead and watch that section
‫so that you really understand what's going on here.
‫Okay, so instead of using this then here
‫I'm gonna use async await
‫and then save the result value of this promise
‫in the new tour variable.
‫Okay, now the final piece of the puzzle here
‫is to of course pass some real data into this create method.
‫And so instead of this empty object
‫we're gonna pass in the request body
‫so req.body and so that's the data
‫that comes with the post request, right?
‫Now just one more time,
‫just to make sure that everything is clear to you.
‫Okay so we can use the tour model directly
‫and call the create method on it.
‫Then into that function we pass the data
‫that we want to store in the database as a new tour.
‫And that data comes from the post body, right?
‫And so that's stored inside of request dot body.
‫So this variable here.
‫Now this method here will then return a promise.
‫And we await that promise using async await
‫and then store that result into the newTour variable
‫which will be the newly created document
‫already with the ID and everything, okay?
‫So I'm gonna keep this code here
‫just as a reference.
‫And for now let's get this piece of data here back.
‫Piece of code actually.
‫Give it a save.
‫And now we get this ES lint error.
‫So let's take a look at that
‫just put our mouse on here.
‫And it tells us that async functions are not supported
‫until this node 7.6
‫and so this ES lint error comes from that node plugin
‫that we actually installed.
‫So you can see that here.
‫Alright, so what we're gonna to do fix this
‫is to simple go to package.json
‫and in here you find the node version
‫that we are actually using.
‫So that's very simple.
‫We just need to specify the engines property
‫here in our json document.
‫And set node to greater or equal
‫than 10.
‫Okay, and that's because in this course
‫we are using at least node ten.
‫So 7.6 would be enough in order to make that error disappear
‫but of course we specify the real version
‫that we're actually using.
‫So we give this one a save.
‫Close that up.
‫And so now our error here is actually gone.
‫Now just one more step before we can actually try this out
‫in our Postman app.
‫And that is that we actually need to handle errors.
‫Okay, and so keep in mind that with async await
‫we need to test for errors using the try catch syntax.
‫So we write a try block.
‫Then wrap all our code in there.
‫And then finally a catch block.
‫Which as we already know has access to the error object.
‫And now what do we actually put here?
‫Well we need to think about
‫when exactly an error can happen.
‫So remember like two lectures ago
‫when we were creating our first documents.
‫We got an error back then
‫when we tried to create a document
‫without one of the required fields, right?
‫And so that was a validation error.
‫And it's one of the errors that would get catched here.
‫Okay because if we tried to create a document
‫let's say without one of the required fields
‫then this promise that is created here
‫would be rejected, okay?
‫And so if we have a rejected promise here
‫then it will enter the catch block.
‫And so therefore, basically in this catch block here
‫we want to send back a response
‫saying that there was an error.
‫Alright so res.status here again
‫and 400 which stands for bad request.
‫.json
‫and now something very similar to this one
‫but its status and that's fail
‫and then instead of data here we send a message
‫and for now lets just set the message to the error.
‫Alright.
‫And let's now finally get back to our Postman application
‫and give this a try.
‫Okay, so create this one
‫and let's now create a new tour.
‫So right now here we have
‫the name duration difficulty and price
‫and so let's actually also add the rating
‫and that needs to be in double quotes
‫4.7.
‫Alright, and now comes the moment.
‫Send and indeed here we go.
‫So this is the tour
‫that we just created.
‫We have our rating.
‫We have our name and we have our price.
‫And of course the automatically created ID.
‫Now you might notice
‫that we have no difficulty and no price.
‫Well why do you think that is?
‫Well that's because these two fields
‫are actually not in our schema
‫and so therefore they are not put in the database.
‫So everything else that is not in our schema
‫is simply ignored.
‫So that is the power of our schema, alright?
‫Great, now let's actually try to send this again
‫and so that should give us an error, right?
‫And indeed there we go.
‫We have our 400 bad request.
‫And we have this message
‫which is the complete error that we got.
‫And so here we see that the error message is duplicate key.
‫And so that's because we already have the Test Tour 2.
‫And so it could not create another one.
‫So let's just create another one here like Jonas Tour.
‫It doesn't really matter, okay?
‫I just wanna create it,
‫first without any of this
‫just to see if we get another error.
‫And indeed we get some more errors here.
‫This time saying that
‫that the tour validation failed
‫because a tour must have a price.
‫Okay, so you see that right now we have
‫this kind of weird error structure here.
‫So Mongo DB gives back this huge complete error object.
‫And later on we're actually gonna take care of that.
‫So we will have an entire section on error handling alone.
‫And by then we will create some more meaningful errors.
‫Okay, for now let's just replace this error object
‫with some normal string here.
‫So let's say invalid data sent.
‫Okay, so don't do something like this
‫in a real production application
‫but again we're gonna have some real error handling
‫a bit later which is gonna take care of that.
‫Okay, so displaying meaningful errors to the client.
‫So let's just go back here
‫send it again.
‫And so now we get this normal string here.
‫So let's just create the price here.
‫Let's set it to 567
‫then send it.
‫And so now you will see
‫that our default rating here is actually still working.
‫Let's now figure all of this out in compass as well.
‫And indeed we get our four tours in the database.
‫So all these weird tests
‫that we've been doing up until this point.
‫So let's just go ahead and delete these last two.
‫That were really just for testing.
‫Alright.
‫So something went wrong here I guess.
‫Okay, now we're back to these two.
‫Let's now just create the third one
‫that we actually had before in the last section.
‫Which is the Snow Adventurer.
‫So the Snow
‫Adventurer.
‫The price was ...
‫I'm not sure anymore
‫like 697 maybe.
‫And the rating is like six
‫or actually 4.8.
‫Sent that guy.
‫And so indeed here we go.
‫Great.
‫Just to quickly recap our createTour function.
‫So we have a try catch here
‫because we're actually using an async await function here.
‫Right, so we use async await
‫because this tour.create returns a promise
‫that we're awaiting so that we can then store
‫the newly created tour document
‫inside of this variable
‫and then send it along with the response
‫to the client down here.
‫Okay but in case there is an error,
‫like a validation error for example
‫then that error is gonna be catched
‫and we send something else back to the client
‫with this error message.
‫So this is how we create documents using mongoose.
‫Next up we're gonna talk about reading documents.