Coding

NodeJS / Express / MongoDB – Build a Shopping Cart – #17 Storing Orders in the Database

  • 00:00:00 here is where we left we have our
  • 00:00:03 shopping cart page you can add items to
  • 00:00:05 our shopping cart we can get then go to
  • 00:00:07 it click on checkout enter some dummy
  • 00:00:10 data here of course enter a dummy credit
  • 00:00:14 card number enter well any valid dummy
  • 00:00:18 data down here and then we can buy this
  • 00:00:21 but currently what the spying really
  • 00:00:23 mean it means that we're emptying the
  • 00:00:26 shopping cart opping cart and that we're
  • 00:00:28 making a charge and we can see the
  • 00:00:30 charges here in the stripe dashboard yes
  • 00:00:34 I was making quite a lot of test charges
  • 00:00:36 yesterday and here under payments we can
  • 00:00:39 see all these charges but of course
  • 00:00:42 we're not really storing the order in
  • 00:00:44 the database so we asked the seller of
  • 00:00:47 the items have no chance of actually
  • 00:00:49 shipping the items to the customer we
  • 00:00:52 would have to Wells kind of try to
  • 00:00:54 contact him through the data we got on
  • 00:00:56 our payments and well that is really a
  • 00:00:59 limited data as you see so that's not
  • 00:01:03 really the best experience we're getting
  • 00:01:04 money well that's certainly good but
  • 00:01:06 we're not delivering anything to your
  • 00:01:08 customer and the customer on the uber
  • 00:01:10 ahead of course as he's not locked in
  • 00:01:13 hasn't a way of seeing the orders on
  • 00:01:16 user profile page or anything like that
  • 00:01:18 so that's certainly something we need to
  • 00:01:20 improve too so what are the next steps
  • 00:01:24 required well we want to be able to
  • 00:01:26 actually store orders in the database
  • 00:01:28 when a user makes a charge and we want
  • 00:01:31 to force the user to log in when
  • 00:01:33 actually checking out and we also want
  • 00:01:36 to show the old orders in the user
  • 00:01:40 profile page so let's work on that
  • 00:01:42 step-by-step I'll start with the first
  • 00:01:46 step of storing orders in the database
  • 00:01:49 for that I'll go to my code and in the
  • 00:01:53 models folder I'm going to create a new
  • 00:01:55 model I'll name it order so in the order
  • 00:01:57 dot JS file here that will be a mongoose
  • 00:02:00 model so I'll copy the product model
  • 00:02:03 here for example rename it to order
  • 00:02:06 instead of product and of course also
  • 00:02:09 change to schema
  • 00:02:10 now what should my order have well it
  • 00:02:13 should refer to the user who made the
  • 00:02:15 order so it will have a user field which
  • 00:02:19 will be of type type what of type schema
  • 00:02:24 types object ID because this field will
  • 00:02:27 hold an ID referring to the user object
  • 00:02:31 we created here or we create here this
  • 00:02:34 user model so we'll store an ID and
  • 00:02:36 we'll let Mongoose know that we have a
  • 00:02:39 reference here with the raft key and we
  • 00:02:42 set a reference to the user model so
  • 00:02:45 with that setup we're basically telling
  • 00:02:46 Mongoose hey actually store an ID here
  • 00:02:50 but behind the scenes you should be
  • 00:02:52 aware that this ID links to the users
  • 00:02:55 collection and to the user model so
  • 00:02:58 that's our user we also want to store
  • 00:03:01 the shopping cart which was purchased on
  • 00:03:03 the order right so here this will be off
  • 00:03:08 type object because we will store a
  • 00:03:11 complete card object and we can't do
  • 00:03:13 that in a note or in a Mongo database
  • 00:03:16 really good because it's stored as JSON
  • 00:03:19 anyway so storing objects is really
  • 00:03:22 simple and works great and I want to set
  • 00:03:27 this to be required then I also want to
  • 00:03:33 store the address of the user who made
  • 00:03:36 the purchase because of course we in
  • 00:03:38 theory would need some kind of shipping
  • 00:03:39 address right this should be a string
  • 00:03:42 and also required and thereafter I also
  • 00:03:46 need to name off the personal purchases
  • 00:03:48 and remember we do have input fields for
  • 00:03:51 all these things on our checkout form so
  • 00:03:54 this should also be a string and all to
  • 00:03:56 be required and finally I want to store
  • 00:04:00 the payment ID now what's the payment ID
  • 00:04:04 well it should be a string and required
  • 00:04:06 and the payment ID can be seen on our
  • 00:04:09 stripe dashboard if we go to payments to
  • 00:04:12 see all past payments and then you click
  • 00:04:14 on any payment you see this ID here
  • 00:04:17 that's the payment ID and I want to
  • 00:04:19 store this idea in my orders collection
  • 00:04:23 on each order item because I want to be
  • 00:04:26 able to map an order to and head to a
  • 00:04:28 payment ID here so that I am able to see
  • 00:04:31 I at this payment refers to this order
  • 00:04:33 this will make it very easy for me to
  • 00:04:35 make this connection so I'm storing that
  • 00:04:38 too with that my order model is
  • 00:04:40 successfully set up the next step of
  • 00:04:42 course is to actually well create orders
  • 00:04:45 and store them in the database the place
  • 00:04:48 to do this is in the index chess file in
  • 00:04:51 the routes folder where I make my charge
  • 00:04:53 and here of course in a callback
  • 00:04:55 function below the error check so if I
  • 00:04:58 know that I don't have an error so since
  • 00:05:02 I want to use my order I'm going to
  • 00:05:03 import it here at the top fruity require
  • 00:05:06 keyword import it from the models folder
  • 00:05:09 of course here from the order file
  • 00:05:11 without the file extension whoops like
  • 00:05:15 this and then down here as I said after
  • 00:05:18 this checking if we do have an error I
  • 00:05:21 want to create a new order and save it
  • 00:05:23 to the database so I'll create a new
  • 00:05:27 variable which should be a new order and
  • 00:05:29 I'll pass a JavaScript object as an
  • 00:05:32 argument which should well initialize my
  • 00:05:35 order so I'll have the user here and the
  • 00:05:40 first step of course is I need to get my
  • 00:05:43 user well that's no problem in theory
  • 00:05:46 because later on I will force the user
  • 00:05:49 to be authenticated in order to make a
  • 00:05:51 check out so right now it's possible to
  • 00:05:54 well make a check out anonymous but
  • 00:05:57 later on I will fix this therefore I
  • 00:05:59 will hear fetch the user from my request
  • 00:06:02 and now you might say well the user why
  • 00:06:06 is it stored in the request on the user
  • 00:06:09 field here while Passport does this for
  • 00:06:12 us since I'm using passport in this
  • 00:06:14 application whenever I sign in with
  • 00:06:17 passport passport we'll place this user
  • 00:06:20 object here on the request and therefore
  • 00:06:23 throughout my whole application I can
  • 00:06:25 always access this user object I can
  • 00:06:28 also well accesses to check if the user
  • 00:06:31 is logged in but here I have later on
  • 00:06:34 know that the users
  • 00:06:35 because again I will implement such a
  • 00:06:38 functionality so I'm fetching the user
  • 00:06:41 from my request next I also want to
  • 00:06:44 store the card and I'm already
  • 00:06:46 extracting my card up here right so I
  • 00:06:49 can just set this equal to Cart
  • 00:06:51 then I'll store my address and now this
  • 00:06:55 currently does not work
  • 00:06:57 I want to retrieve it from the post
  • 00:06:59 request which is sent to this checkout
  • 00:07:01 route but if we have a look at the
  • 00:07:04 checkout view here which is where we
  • 00:07:06 issued that post request we do have this
  • 00:07:09 address field but currently doesn't have
  • 00:07:12 a name attribute on it so we would not
  • 00:07:15 be able to retrieve it from the request
  • 00:07:16 in order to be able I'll add this name
  • 00:07:19 attribute to it and well I'll put the
  • 00:07:21 name address on it I'll also give the
  • 00:07:25 name input field up here this name
  • 00:07:28 attribute and I'll name it name well
  • 00:07:31 there are a lot of names but in the end
  • 00:07:33 I just want to be able to retrieve the
  • 00:07:34 value on that input field well on the
  • 00:07:37 name field in my request so I can
  • 00:07:42 retrieve the address on my request body
  • 00:07:44 because remember request body is where
  • 00:07:48 Express stores D well values sent with a
  • 00:07:52 post request so I can retrieve the
  • 00:07:55 address field there since I just created
  • 00:07:58 this and I can retrieve the name exactly
  • 00:08:00 in the same way so request body name so
  • 00:08:04 address and name here of course are the
  • 00:08:07 names I just set up on the view finally
  • 00:08:11 I want to store the payment ID and I can
  • 00:08:14 retrieve that payment ID from my charge
  • 00:08:16 object which gets passed here to the
  • 00:08:18 callback here whoops charge I can simply
  • 00:08:22 access the ID field and how do I know
  • 00:08:25 that the payment ID is stored in an ID
  • 00:08:28 field and not in a field named let's say
  • 00:08:30 payment ID for example well if you have
  • 00:08:33 a look at the stripe documentation you
  • 00:08:35 will see how this response object this
  • 00:08:38 charge object here looks like and then
  • 00:08:40 well there you see that it actually has
  • 00:08:42 this ID field which stores the payment
  • 00:08:44 ID so that's all just reading the
  • 00:08:46 document
  • 00:08:47 here with that my order object is
  • 00:08:50 configured and I can next save it to the
  • 00:08:52 database I will provide a callback here
  • 00:08:56 and this callback of course will either
  • 00:08:58 give me an error or the well result of
  • 00:09:01 this saving operation and what do I want
  • 00:09:04 to do in this callback well I want to
  • 00:09:07 execute all the code I had outside of
  • 00:09:09 this callback here so I'm not checking
  • 00:09:11 for errors here even though well
  • 00:09:13 technically it would be better to kind
  • 00:09:16 off well add if error and then do
  • 00:09:19 something you're like redirect back to
  • 00:09:21 the checkout page something like that
  • 00:09:23 but I'll leave out this for now and just
  • 00:09:26 handle the good case here which should
  • 00:09:29 happen most of the time here on our very
  • 00:09:31 simple application but keep in mind for
  • 00:09:34 real applications you would need to
  • 00:09:36 handle the arrows here so with that I'm
  • 00:09:39 actually saving my order to the database
  • 00:09:41 I'll again tell you that this will only
  • 00:09:46 work if we are locked in so well let's
  • 00:09:50 let's try it I'll restart my server here
  • 00:09:53 go back to my application and reload it
  • 00:09:56 well add something to the shopping cart
  • 00:09:58 click on shopping cart and again I need
  • 00:10:00 to sign in so I'll do this sign in
  • 00:10:03 quickly like this go back to the
  • 00:10:06 shopping cart click on checkout and then
  • 00:10:09 here let's enter some dummy data I'll go
  • 00:10:14 to the strap documentation to fetch this
  • 00:10:16 dummy credit card data here just credit
  • 00:10:20 card number and root here click on buy
  • 00:10:23 now looks good but did it actually save
  • 00:10:28 something to the database
  • 00:10:29 well that's Edward you the MongoDB shell
  • 00:10:33 client here which allows me to have a
  • 00:10:34 look into my database I'll switch to my
  • 00:10:37 shopping database and then here on the
  • 00:10:42 orders collection all we'll find to see
  • 00:10:45 all the orders and as you can see we
  • 00:10:47 actually got a get got an order here
  • 00:10:49 with a user object stored and our card
  • 00:10:54 stored where we see we have well what
  • 00:10:56 Warcraft this is what
  • 00:10:58 but we have the prize and so on so yes
  • 00:11:01 the order is stored we also got the
  • 00:11:03 payment a year and we can verify this
  • 00:11:05 payment ID let's just remember it ends
  • 00:11:08 with we dm7
  • 00:11:10 let's have a look at our stripe account
  • 00:11:12 payments there if I click on the payment
  • 00:11:16 you see the idea right here this is the
  • 00:11:19 payment ID which is the same one as we
  • 00:11:21 saw here so all of that is working but
  • 00:11:24 of course you would get arrows if we
  • 00:11:26 were not logged in so that's certainly
  • 00:11:28 something I need to fix