Coding

#6 Adding Relations | Build a Complete App with GraphQL, Node.js, MongoDB and React.js

  • 00:00:01 hi and welcome back to this series we're
  • 00:00:05 making good progress
  • 00:00:06 we added MongoDB in the last video we
  • 00:00:09 added our event model and we're now able
  • 00:00:11 to actually hit the database when we get
  • 00:00:13 an incoming mutation or when we want to
  • 00:00:15 retrieve our events now let's also make
  • 00:00:18 sure we add users to a picture so that
  • 00:00:21 we get closer to our final API
  • 00:00:23 implementation
  • 00:00:27 so we need more models now we want to
  • 00:00:31 have users and users should be able to
  • 00:00:33 book events so in the models folder here
  • 00:00:36 I will add a user JS file because
  • 00:00:39 obviously we want to define how a user
  • 00:00:43 should look like in our application and
  • 00:00:45 there just as in the last video I will
  • 00:00:48 start by importing mongoose
  • 00:00:53 then i will access this schema object
  • 00:00:57 with this schema constructor provided by
  • 00:01:00 mongoose because i want to create a new
  • 00:01:02 user schema here now as you learn in the
  • 00:01:05 last video we do call new on that schema
  • 00:01:08 constructor and pass a javascript object
  • 00:01:10 to it and there we now define how this
  • 00:01:13 object should look like so how i user
  • 00:01:16 object should look like in our app and
  • 00:01:18 in our database now my users will be
  • 00:01:22 very simple you can't could add tons of
  • 00:01:24 data there the address mobile phone
  • 00:01:27 number i will give my users an email and
  • 00:01:32 dad should then be off type string and
  • 00:01:36 it should be required and my users will
  • 00:01:39 have a password of course and dad will
  • 00:01:41 also be of type string and this will
  • 00:01:44 also be required now that is not all
  • 00:01:48 however of course my users should be
  • 00:01:51 connected to the events and actually
  • 00:01:54 there are two ways how users are
  • 00:01:56 connected to events either they created
  • 00:02:00 an event so in our app we want to enable
  • 00:02:02 users to create events something like
  • 00:02:04 your birthday party or maybe something
  • 00:02:07 else if it costs money the other way we
  • 00:02:11 connect users and events is of course by
  • 00:02:13 bookings that a user booked an event now
  • 00:02:17 let's focus on the bookings later for
  • 00:02:19 now let's add another field here which
  • 00:02:22 i'll name created events so thatis that
  • 00:02:25 connection where we say which user
  • 00:02:27 created which event now created events
  • 00:02:31 will actually be an array so here we
  • 00:02:34 will store an array of data because
  • 00:02:36 obviously a user can create more than
  • 00:02:38 one event and in a mangu
  • 00:02:40 world we depict this relation by first
  • 00:02:44 of all adding square brackets and then
  • 00:02:47 in there we define how a single element
  • 00:02:50 in that array of data would look like so
  • 00:02:52 we have multiple created events
  • 00:02:54 potentially at least each single data
  • 00:02:57 field we store in that array will
  • 00:03:00 however be an object where the type is
  • 00:03:02 now not string not number it will
  • 00:03:06 instead be schema types object ID
  • 00:03:11 because we have this special object ID
  • 00:03:14 data type that Mongoose or that MongoDB
  • 00:03:16 uses for its IDs and here we will just
  • 00:03:19 store a list of IDs in the end here we
  • 00:03:23 store all the IDS of the events this
  • 00:03:25 user created now this is not strictly
  • 00:03:28 required we can't have an empty array
  • 00:03:30 when a user is brand-new the array will
  • 00:03:33 be empty but if we add data it should
  • 00:03:35 look like this so the elements in there
  • 00:03:37 should simply be IDs and by the way this
  • 00:03:40 year just to make this really here does
  • 00:03:42 not mean that we add objects to created
  • 00:03:45 events we add instead data fields we add
  • 00:03:50 our object IDs our IDs here so we will
  • 00:03:53 have multiple IDs in that array multiple
  • 00:03:55 string like objects one special field I
  • 00:03:59 add here in the in the definition of how
  • 00:04:02 my data looks like is the ref field
  • 00:04:04 however this is important internally for
  • 00:04:06 Mongoose because this allows me to set
  • 00:04:08 up a relation and let Mongoose know that
  • 00:04:11 two models are related which will later
  • 00:04:15 help us when we fetch data because then
  • 00:04:17 we can basically let Mongoose
  • 00:04:18 automatically merge data which is really
  • 00:04:21 cool ref takes a string and now it's
  • 00:04:24 important here we use the name of the
  • 00:04:27 model to which we want to connect this
  • 00:04:29 so here we want to connect this to the
  • 00:04:31 event model and in my event model file
  • 00:04:34 I chose event as a name like this so we
  • 00:04:38 should use that exact same name here
  • 00:04:40 with these same casing and so on and now
  • 00:04:42 we're telling Mongoose that there is a
  • 00:04:44 connection so that we store object IDs
  • 00:04:47 and created events and that this will
  • 00:04:49 actually be object IDs from my event
  • 00:04:52 model otherwise mongoose couldn't
  • 00:04:54 out because object IDs don't have
  • 00:04:56 metadata in them to which model they
  • 00:04:58 belong so now we have disconnection of
  • 00:05:01 course we also want to set it up in the
  • 00:05:03 other model in the event model every
  • 00:05:05 event should actually be created by a
  • 00:05:08 user so here I will add a creator field
  • 00:05:11 and now this will not be an array
  • 00:05:14 because every event will only have one
  • 00:05:16 creator so here instead this will be of
  • 00:05:18 type schema types object ID just as in
  • 00:05:26 the our um model and I will also set up
  • 00:05:29 a reference here and here the reference
  • 00:05:31 will of course point at my user model
  • 00:05:33 now I haven't given this model any name
  • 00:05:36 yet because I haven't called mongoose
  • 00:05:37 model yet but i will name this user
  • 00:05:40 eventually so I will use that name here
  • 00:05:42 and now of course in the user J's file
  • 00:05:45 when I create that Mon model with
  • 00:05:47 Mongoose model I should make sure that I
  • 00:05:50 name it user like this here too and
  • 00:05:52 there I will point at my user schema and
  • 00:05:54 just as before I want to export this so
  • 00:05:57 I will call or I will set module exports
  • 00:06:00 equal to that model
  • 00:06:01 now we created a user model and that is
  • 00:06:04 now actually connected to our events now
  • 00:06:07 I'll quickly go back by the way into my
  • 00:06:10 collection view or if you don't have
  • 00:06:12 that into MongoDB comm-pass and there
  • 00:06:14 you can clean up data I'll quickly
  • 00:06:16 refresh to see all the events I created
  • 00:06:18 since these don't have a creator I will
  • 00:06:21 actually delete them here to make sure
  • 00:06:23 that I don't have invalid data in my
  • 00:06:26 database so let's get rid of all of that
  • 00:06:27 and now go back to our code because
  • 00:06:31 adding this model is a nice first step
  • 00:06:34 we'll work on the booking later
  • 00:06:36 now let's of course make sure that we
  • 00:06:39 actually are able to create new users
  • 00:06:41 and that we actually also add the user
  • 00:06:45 ID to a newly created event and that we
  • 00:06:48 then add the event ID to the user so
  • 00:06:51 let's get there step by step go back to
  • 00:06:53 app J s and let's tweak our graph QL
  • 00:06:56 schema and we'll outsource this into a
  • 00:06:59 separate file eventually by the way
  • 00:07:00 there we now don't just have events we
  • 00:07:03 also have a new type to user type right
  • 00:07:06 I
  • 00:07:08 user will also have an ID underscore ID
  • 00:07:12 to be precise will have an email which
  • 00:07:15 will be required an on Nala bilang and
  • 00:07:18 will have a password and now the
  • 00:07:20 password will actually be nullable so I
  • 00:07:24 won't add an exclamation mark here
  • 00:07:25 because will not always guarantee that a
  • 00:07:30 password is set because when we fetch
  • 00:07:33 user data I never want to return that
  • 00:07:36 password you should never be able to
  • 00:07:38 access that password we'll need it when
  • 00:07:41 we create a user but we will not be able
  • 00:07:43 to ever retrieve it from the database so
  • 00:07:46 in my resolver I will make sure that I
  • 00:07:48 don't return the password therefore this
  • 00:07:50 is actually nullable now of course we
  • 00:07:54 also can create users so we'll add a new
  • 00:07:56 input data type and I'll name it user
  • 00:07:59 input and when I create a user there I
  • 00:08:02 will have an email which is non
  • 00:08:04 malleable and a password and here the
  • 00:08:06 password will also be non malleable
  • 00:08:08 because when I create a user or when I
  • 00:08:10 try to login a user I need to F password
  • 00:08:13 so if it's passed in from the outside
  • 00:08:15 from the front that I absolutely want it
  • 00:08:17 but it will never return it so therefore
  • 00:08:21 here I got this user input type now we
  • 00:08:24 obviously need the filling queries and
  • 00:08:26 mutations so let's start with the create
  • 00:08:29 user mutation you can name it however
  • 00:08:32 you want I will name it create user and
  • 00:08:34 there I believe my user input and it
  • 00:08:37 will return the user object to kind of
  • 00:08:41 give di a give an idea of which user was
  • 00:08:43 created this is it for now let's now go
  • 00:08:47 down to the resolvers and there after
  • 00:08:49 create event I will add to create user
  • 00:08:53 resolver now just as before this will
  • 00:08:57 get my arguments so my user input in
  • 00:09:02 this case and now I can add logic to
  • 00:09:04 create a user in the database for this
  • 00:09:07 let's first of all import that user
  • 00:09:11 model by requiring it from slash models
  • 00:09:14 user and down there when I create that
  • 00:09:20 user
  • 00:09:21 I will create a user object with new
  • 00:09:23 user there I need to set an email and a
  • 00:09:27 password
  • 00:09:28 obviously when storing it in the
  • 00:09:29 database we need a password so we'll
  • 00:09:32 access our X user input just as I did it
  • 00:09:35 with our X event input up there and then
  • 00:09:38 there should be an email input because
  • 00:09:40 that is how I defined it in my graph QL
  • 00:09:42 schema there in user input I defined
  • 00:09:45 that there would be an email and a
  • 00:09:47 password now we are accessing the email
  • 00:09:49 now let's go down let's do the same for
  • 00:09:51 the password so here I will also add
  • 00:09:54 password our X user input dot password
  • 00:09:58 and this would be a huge security flaw
  • 00:10:02 already now do you see what's wrong with
  • 00:10:04 this way of storing the user data in the
  • 00:10:07 database well if we store it like this
  • 00:10:09 then we would store the password as
  • 00:10:12 plain text in the database and no matter
  • 00:10:15 if we use SSL encryption for
  • 00:10:17 transmitting the data to the server at
  • 00:10:20 this point of time it would be plain
  • 00:10:22 text and it would end up as plain text
  • 00:10:24 in the database and if anyone ever hacks
  • 00:10:27 our database or is some employee who
  • 00:10:30 doesn't like us has access to the
  • 00:10:31 database then our user passwords are
  • 00:10:34 exposed as plain text and we absolutely
  • 00:10:36 don't want to have that so we should
  • 00:10:39 create a hashed password which can't be
  • 00:10:42 decrypted basically for data will quit
  • 00:10:45 my development server and I will install
  • 00:10:47 a new package which is called decrypt
  • 00:10:49 j/s and this gives us some cryptographic
  • 00:10:52 methods that help us creating a hash
  • 00:10:55 which you can later also compare to an
  • 00:10:58 incoming password to see if the incoming
  • 00:11:00 password is correct but which we can't
  • 00:11:03 build back so which we can't get the
  • 00:11:07 original password from so with that
  • 00:11:09 installed I can restart my development
  • 00:11:11 server and now here I will actually
  • 00:11:13 import be tripped by requiring bcrypt
  • 00:11:17 j/s here and now we can use that down
  • 00:11:20 there and create user and we'll do that
  • 00:11:23 before I create the user object I will
  • 00:11:25 call be tripped and then there is this
  • 00:11:27 hash method and hash takes as a first
  • 00:11:32 argument the string we want to hash so
  • 00:11:34 in my case the
  • 00:11:35 hazard rx user input password and the
  • 00:11:40 second argument is assault
  • 00:11:42 now this is basically this defines the
  • 00:11:44 security of the generated hash and
  • 00:11:46 twelve rounds of salting are considered
  • 00:11:49 safe now this gives us a promise because
  • 00:11:52 this actually is a asynchronous task it
  • 00:11:55 could fail for some reason in this case
  • 00:11:58 I want you throw an error and it could
  • 00:12:02 also succeed of course and in this case
  • 00:12:05 I will have my hashed password and I
  • 00:12:10 then want to use that here and now I
  • 00:12:12 will create that user inside of this
  • 00:12:13 then block once I have the hashed
  • 00:12:15 password and I will store that hashed
  • 00:12:17 password in the database now since this
  • 00:12:20 is a asynchronous task and we are in a
  • 00:12:22 resolver we want graph QL or Express
  • 00:12:25 graph QL to wait for us so I will return
  • 00:12:28 this so that Express graph you will
  • 00:12:30 notice that we got a asynchronous
  • 00:12:32 operation and it should basically go
  • 00:12:34 into that promise chain and wait for its
  • 00:12:37 to be resolved and now we are on a good
  • 00:12:40 road to save our users but we're not
  • 00:12:44 there yet we created user object but we
  • 00:12:46 don't save it to the database so we want
  • 00:12:49 to call save here and this returns this
  • 00:12:51 promise like object which we can also
  • 00:12:53 return in here so that in the next then
  • 00:12:57 block we actually now have the result of
  • 00:12:59 this operation or an error which will be
  • 00:13:02 handled by catch still and in there
  • 00:13:04 I now have the result of this operation
  • 00:13:06 this is now the created user so here I
  • 00:13:10 can now return just as before result
  • 00:13:14 underscore doc and also overwrite the ID
  • 00:13:19 to be result ID using that virtual
  • 00:13:22 gather provided by Mongoose now let's
  • 00:13:27 give this a try I have create user in
  • 00:13:29 place here should work I have my schema
  • 00:13:32 definition updated let's go back to
  • 00:13:35 graphical and there let's create a new
  • 00:13:37 mutation and you need to reload that
  • 00:13:42 page to have correct Auto completion
  • 00:13:44 again so now I have created user here as
  • 00:13:47 an option
  • 00:13:48 I can pass my user input and there I
  • 00:13:50 have my email for example test at test
  • 00:13:53 comm and I also want to have my password
  • 00:14:01 here tester and then I want to return
  • 00:14:05 something and let's actually try to get
  • 00:14:07 both the email and the password if I now
  • 00:14:10 it enter this generally looks good we
  • 00:14:13 were able to create our user otherwise
  • 00:14:15 you would have got an error you can also
  • 00:14:17 check this in the database if i refresh
  • 00:14:20 there you know i collection do I have to
  • 00:14:23 the users collection now and there I
  • 00:14:24 have that user we also see that the
  • 00:14:26 password is hashed but we also see that
  • 00:14:29 I'm able to retrieve the password and
  • 00:14:32 yes it's the hashed password and this is
  • 00:14:34 pretty secure but I actually don't even
  • 00:14:37 want to retrieve it because where would
  • 00:14:38 you ever need that it is useful for
  • 00:14:41 nothing and it still is even a tiny but
  • 00:14:44 it is still a security issue so I don't
  • 00:14:47 want to return my password here and one
  • 00:14:50 easy fix is to go down there where I
  • 00:14:52 create my user and I will override the
  • 00:14:55 password and I will always set it to
  • 00:14:57 null not password which I'll store in
  • 00:15:00 the database just a password which I
  • 00:15:02 retrieved thereafter so now if I run
  • 00:15:04 that same query again you see password
  • 00:15:06 is actually null I'm not able to get
  • 00:15:08 this it's now nullable or it was
  • 00:15:11 inaudible before but now I'm taking
  • 00:15:12 advantage of this when everything you
  • 00:15:15 might have noticed is that if i refresh
  • 00:15:17 my collection again I now I have two
  • 00:15:19 users with the same email address and I
  • 00:15:21 don't want to have that in there as well
  • 00:15:24 so what it will actually do first before
  • 00:15:26 I even create my user I will look for a
  • 00:15:30 user with this email address in my
  • 00:15:32 database and I can use that user address
  • 00:15:34 and add user object and there I can use
  • 00:15:37 find one to find one single user because
  • 00:15:39 if one user with that email address
  • 00:15:41 exists it's already too many and there
  • 00:15:44 shouldn't be more than one of course I
  • 00:15:46 will add my filter criterium here
  • 00:15:49 between curly braces and I'll look for
  • 00:15:52 the email address being equal to RX user
  • 00:15:55 input email and then here I have my then
  • 00:16:00 a my catch block
  • 00:16:02 and let's ignore a catch for now because
  • 00:16:04 I will solve this differently anyways
  • 00:16:06 but in the then block here I get my user
  • 00:16:09 and now the way Mongoose works is
  • 00:16:12 actually not such that if we make it
  • 00:16:15 into then we have a user and if we don't
  • 00:16:18 make it into there we have no user we
  • 00:16:21 will always end up in the van block
  • 00:16:23 unless we have a connection error or or
  • 00:16:25 some permission air or any other error
  • 00:16:28 but otherwise we'll always end up there
  • 00:16:30 and user IVA is undefined if there is no
  • 00:16:33 user that matches our filter or it will
  • 00:16:36 be an object and for us this means that
  • 00:16:39 if user if this is true ish which it
  • 00:16:42 would not be if it's undefined and we're
  • 00:16:44 looking for the undefined case of course
  • 00:16:46 because we were looking for the case
  • 00:16:48 where there is no user but if this is
  • 00:16:50 true ish which means there is a user
  • 00:16:51 then we have a problem and then I want
  • 00:16:54 to throw a new error whereas a user
  • 00:16:58 exists already otherwise if we make it
  • 00:17:05 past this if Jack I know this user does
  • 00:17:07 not exist yet so we can safely continue
  • 00:17:10 and now I want to return be tripped hash
  • 00:17:15 and when I return this in this then
  • 00:17:17 block and now I can chain my next then
  • 00:17:20 block on to this so now we would
  • 00:17:22 continue with the other chain if you
  • 00:17:25 throw this error we skip all our then
  • 00:17:27 blocks and we can write in there and
  • 00:17:29 return this error back to graph QL so
  • 00:17:32 now if I save dad let's try that again
  • 00:17:34 exact same mutation with the existing
  • 00:17:37 email address and now you see I get back
  • 00:17:41 null here and create user problem is of
  • 00:17:45 course that I don't return my promise
  • 00:17:50 here and therefore agrea graph QL
  • 00:17:51 finished too early or didn't wait for
  • 00:17:53 this promise chain to resolve so let's
  • 00:17:56 add return and save again and now I get
  • 00:17:59 an error user exists already which is
  • 00:18:01 what I want and if I go back to my
  • 00:18:04 collection view here in the database and
  • 00:18:07 I quickly clean up these duplicate
  • 00:18:09 entries so I clean up all my users for
  • 00:18:12 now here as well
  • 00:18:15 if I do all of that now we have no users
  • 00:18:20 in the database now I am able to run
  • 00:18:23 this again and I added this user to my
  • 00:18:25 collection because we had no user now if
  • 00:18:28 I reload we will see that single user we
  • 00:18:30 just added of course but if I now rerun
  • 00:18:32 this I would get this error again and
  • 00:18:34 thereafter if i refresh we still only
  • 00:18:37 have one user because we didn't hit the
  • 00:18:39 database instead we threw that error and
  • 00:18:41 we didn't continue so that's great we're
  • 00:18:44 now able to create users we didn't
  • 00:18:46 really add a login or anything like that
  • 00:18:47 we'll do this later the last thing I
  • 00:18:50 want to do is I want to be able to
  • 00:18:52 connect my created events with a user
  • 00:18:55 and for that and my models I've already
  • 00:18:58 prepared something I have to create or
  • 00:19:00 field on the event for example where I
  • 00:19:03 want to store the object ID off the user
  • 00:19:05 who created the event now later once we
  • 00:19:08 added authentication we'll be able to
  • 00:19:10 retrieve that object ID automatically
  • 00:19:13 because we'll basically add a header to
  • 00:19:16 our requests to pass that on and it will
  • 00:19:19 take care about this later for now I
  • 00:19:22 will use a simpler approach I will copy
  • 00:19:25 my object ID so this string here is
  • 00:19:28 enough off the user which I will now use
  • 00:19:31 as a dummy user for all created events
  • 00:19:33 and again we will change this later and
  • 00:19:35 an app j/s when we create an event I
  • 00:19:38 will attach this 2d created event so
  • 00:19:42 here on the event I'm creating I will
  • 00:19:45 now add the creator field because that
  • 00:19:47 is the name I assign in my schema and
  • 00:19:49 there I now want to store the ID of the
  • 00:19:53 user and again I will hard code this for
  • 00:19:56 now and the cool thing with mongooses
  • 00:19:59 I can't just pass a string there and
  • 00:20:01 Mongoose will automatically convert this
  • 00:20:03 to an object ID which we ultimately need
  • 00:20:05 you need to store an object ID so that
  • 00:20:08 MongoDB can work with it but mangu estas
  • 00:20:10 this conversion for us so we can just
  • 00:20:12 pass a string here and now we will save
  • 00:20:15 that user as the creator of this event
  • 00:20:17 if you remember however in our user
  • 00:20:20 model we also have to create an events
  • 00:20:22 key so once we created the event I also
  • 00:20:25 want to add an entry to the user
  • 00:20:27 to make clear hey this user has these
  • 00:20:30 events which were created by the user
  • 00:20:33 and they offered now I will go back to a
  • 00:20:35 purchase once I called safe and I have
  • 00:20:38 my events stored I will actually not
  • 00:20:40 return a response where a result for the
  • 00:20:43 resolver immediately instead here I now
  • 00:20:46 want you edit my user and for that I
  • 00:20:50 will call user find by ID and I'll find
  • 00:20:56 that user with the for now hard-coded ID
  • 00:20:58 and I will return this here so that I
  • 00:21:03 can simply add a new land block here and
  • 00:21:05 there I will have my user now of course
  • 00:21:08 we could somehow have a case where we
  • 00:21:10 don't find a user for that ID so if that
  • 00:21:13 is the case I will actually throw an
  • 00:21:15 error but that is very unlikely and it
  • 00:21:17 won't happen here because I hard-code
  • 00:21:19 the idea of a user who does exist but if
  • 00:21:22 we make it past as if check we know a
  • 00:21:23 user exists and now we can simply edit
  • 00:21:26 the created events so this field we can
  • 00:21:30 simply edit this on the user and call
  • 00:21:35 push there and this is a method provided
  • 00:21:37 by Mongoose and there we pass the event
  • 00:21:41 so our event object there or just the
  • 00:21:45 idea of the event that is enough to we
  • 00:21:46 could pass both Mongoose is able to
  • 00:21:48 handle both if we pass the whole object
  • 00:21:50 Mongoose will pull out the ID if we pass
  • 00:21:52 just the idea it's fine anyways so here
  • 00:21:55 I will just pass the entire event object
  • 00:21:57 which I'm creating up here and this has
  • 00:21:59 to be an object based on a mongoose
  • 00:22:01 model which is this so now i passed this
  • 00:22:03 whole event object and thereafter i will
  • 00:22:06 return user save here so that i access
  • 00:22:10 the database and and update the user
  • 00:22:11 this will now not create a new user it
  • 00:22:13 will update the existing user and
  • 00:22:15 therefore we add whenever then block
  • 00:22:18 here there i got the result of this
  • 00:22:21 operation and now i want to return what
  • 00:22:25 do i return well still an event right
  • 00:22:27 and now we have a problem if i copy my
  • 00:22:30 old return statement there I returned
  • 00:22:34 result doc and so on but the doc is now
  • 00:22:37 actually the user document of the
  • 00:22:39 updated user so if I want to return
  • 00:22:41 the created event there I need to do
  • 00:22:43 this in a different way and I will do it
  • 00:22:46 in a very simple way I will treat a new
  • 00:22:49 variable created event up there which is
  • 00:22:52 initially undefined but once I have my
  • 00:22:55 event created which is the case in this
  • 00:22:57 then block I will actually set created
  • 00:23:00 event equal to what I previously
  • 00:23:04 returned here like this oops created
  • 00:23:12 event should be the name of course so
  • 00:23:16 we'll set created event equal to that
  • 00:23:18 and then down there once I added my user
  • 00:23:22 I will just return that created event
  • 00:23:27 here now let's give this a try let's
  • 00:23:30 save that let's go back to graphical and
  • 00:23:34 let's create a new mutation here the
  • 00:23:38 create event mutation with the event
  • 00:23:40 input and there we want to have a title
  • 00:23:44 testing description this is a test a
  • 00:23:49 price of course 9.99 and we need to good
  • 00:23:53 old date again where I will again
  • 00:23:56 generate it with the help of the
  • 00:23:58 developer tools here this is my date
  • 00:24:01 string I want to use let's close that
  • 00:24:04 it's inserted here and then 40 created
  • 00:24:07 event I want to get my title and I want
  • 00:24:10 to get my description and I get user
  • 00:24:14 exists' already so that through an error
  • 00:24:18 well the message is wrong anyways and of
  • 00:24:20 course the check is wrong I should check
  • 00:24:22 for the opposite if we don't have a user
  • 00:24:24 and then I should return user not found
  • 00:24:26 my bad
  • 00:24:27 just copying that was of course and not
  • 00:24:29 enough I have to check the opposite
  • 00:24:32 because here the problem is if I don't
  • 00:24:33 have a user not if I have a user so
  • 00:24:36 let's try it again this looks better now
  • 00:24:38 now here I actually created that event
  • 00:24:42 and if I now go into my events a
  • 00:24:44 collection we will see it this worked
  • 00:24:46 and I actually have two events here
  • 00:24:49 simply because previously I messed up
  • 00:24:53 because of my error so I will
  • 00:24:55 remove one of these events and by the
  • 00:24:57 way if you want to handle such a case
  • 00:24:59 where you have like two operations on
  • 00:25:01 the database that kind of works together
  • 00:25:03 you could use a transaction maybe I'll
  • 00:25:06 add that later
  • 00:25:07 MongoDB supports transactions since
  • 00:25:09 version four I do cover them in my
  • 00:25:11 course for now don't want to dive too
  • 00:25:13 deep into MongoDB so let's leave it like
  • 00:25:15 this this error is fixed anyways now we
  • 00:25:17 have one event here and that event has
  • 00:25:20 the Creator this is our user ID and we
  • 00:25:23 can check the users all remember this
  • 00:25:26 event ID
  • 00:25:27 it ends with EB 4 if I go to the users
  • 00:25:30 collection you see there we have to
  • 00:25:32 create an events array and there we have
  • 00:25:34 an event ok this is not a different
  • 00:25:36 event because I am actually deleted two
  • 00:25:39 wrong one of my duplicate events let's
  • 00:25:42 fix this let's still eat this event here
  • 00:25:44 real quick let's go back to users and in
  • 00:25:47 this array we can add at this by
  • 00:25:50 clicking this pen icon let me delete
  • 00:25:53 this object ID in there update now I
  • 00:25:59 removed that event from the user and now
  • 00:26:03 if I simply create the event again now
  • 00:26:05 we have a clean set up and now you will
  • 00:26:07 see if you go back to events really
  • 00:26:09 quick here is our event with the user
  • 00:26:12 object ID and it ends with a CA 6 and if
  • 00:26:16 we go back to the users collection we
  • 00:26:18 see under created events there is this
  • 00:26:20 event ID so now this connection between
  • 00:26:23 events and users all the works we are
  • 00:26:25 now able to create users and create
  • 00:26:27 events that are connected to users
  • 00:26:29 that's a huge step forward
  • 00:26:32 now obviously bookings are still missing
  • 00:26:34 real authentication is still missing so
  • 00:26:36 there still is work left to do but we're
  • 00:26:39 making good progress and I hope I can
  • 00:26:41 welcome you back in the next part of
  • 00:26:43 this series