Coding

#21 Improving Queries & Bugfixing | Build a Complete App with GraphQL, Node.js, MongoDB and React.js

  • 00:00:01 hi and welcome back great to see you're
  • 00:00:04 still on board this will be a back
  • 00:00:07 fixing and improvements video because
  • 00:00:09 there are two things which I basically
  • 00:00:11 wanna fix or improve one is related to
  • 00:00:15 data loader which we added in the last
  • 00:00:17 video of this series and one is an issue
  • 00:00:20 not really an issue but something we can
  • 00:00:22 improve that has been in our code for a
  • 00:00:25 couple of videos already so let's dive
  • 00:00:28 in and let's make sure we can slowly but
  • 00:00:30 steadily finish up this project
  • 00:00:35 so what do I want to change the app as
  • 00:00:39 we have it here actually works just fine
  • 00:00:42 if you do login here you can use all the
  • 00:00:46 different parts of it without any issues
  • 00:00:48 that all works and it's good and data
  • 00:00:50 loader is doing its job and reduced the
  • 00:00:52 amount of round trips we do but there
  • 00:00:55 still is an issue with this application
  • 00:00:58 as we have it and that can be seen when
  • 00:01:02 we actually don't use the front-end you
  • 00:01:05 react front-end but if we have a look at
  • 00:01:07 the app chess we wizard slash graph tool
  • 00:01:09 with a get request and therefore we use
  • 00:01:11 graphical there's testing tool for our
  • 00:01:14 graph QL API so if a wizard localhost /
  • 00:01:17 graph QL which is the URL to graphical
  • 00:01:20 then here we can write any graph till
  • 00:01:23 curry we want and we use graphical
  • 00:01:25 earlier in this series already so you
  • 00:01:28 might still know that now here let me
  • 00:01:30 show you which issue we currently have
  • 00:01:32 if I get my events so let's say I get
  • 00:01:35 the IDS that just works now let's say I
  • 00:01:38 also get information about the creator
  • 00:01:40 like the let's see the email maybe that
  • 00:01:45 also works but now let's say for every
  • 00:01:48 creator we want to know which events
  • 00:01:50 this person created so I'll get the
  • 00:01:53 created events here and there for every
  • 00:01:56 event the title doesn't really matter
  • 00:01:58 what you fetch there now we actually get
  • 00:02:00 an error cannot read property get of
  • 00:02:02 undefined and this is related to a bug
  • 00:02:05 which I introduced in the last video
  • 00:02:08 there I add a data loader in the merge
  • 00:02:11 JS file here with event loader and user
  • 00:02:13 loader and we use the load method to
  • 00:02:17 load for example a related event here or
  • 00:02:20 to batch all these event requests
  • 00:02:22 together in this case now for created
  • 00:02:25 events I use event loader load and then
  • 00:02:28 I pass my user created events now the
  • 00:02:32 issue here is first of all we shouldn't
  • 00:02:34 use load here but I actually want to
  • 00:02:36 load multiple items here
  • 00:02:39 I pass an array of event IDs here not a
  • 00:02:42 single event and they are four instead
  • 00:02:44 of load this should be load many now
  • 00:02:49 it still would not work though if we use
  • 00:02:51 it like this and the reason for that is
  • 00:02:53 simply related to how did this keyword
  • 00:02:55 behaves in JavaScript finding this in
  • 00:02:59 the load many function to the same
  • 00:03:03 reference or object this refers to in
  • 00:03:06 this function will not work and
  • 00:03:08 therefore it's wrong to use event load
  • 00:03:11 or load many bind here but what we can
  • 00:03:13 do is we can simply wrap this in
  • 00:03:15 anonymous function call so this is an
  • 00:03:18 anonymous arrow function where we then
  • 00:03:21 execute event load or load many without
  • 00:03:23 bind and therefore without passing this
  • 00:03:25 as an argument so I just call load many
  • 00:03:28 here but not directly when this code
  • 00:03:30 gets parsed when this function gets
  • 00:03:32 executed but inside of this anonymous
  • 00:03:34 function which I store in the created
  • 00:03:36 events field here and therefore whatever
  • 00:03:39 I fetch created events I execute this
  • 00:03:41 function I call event load or load many
  • 00:03:44 I leave this that this keyword as it is
  • 00:03:47 in load many without rebinding it and
  • 00:03:50 therefore this will work now with that
  • 00:03:53 if I save that if I execute that same
  • 00:03:57 query here you see now that looks way
  • 00:03:59 better and I get back an array of
  • 00:04:01 created events for my user this is test
  • 00:04:05 a test calm and we see test two at test
  • 00:04:08 calm only has one event for example so
  • 00:04:10 now this is the back fixed which I
  • 00:04:13 introduced in the last video now that's
  • 00:04:15 the back but there also something else
  • 00:04:17 which have one improved and that is
  • 00:04:19 right to our front-end there for example
  • 00:04:22 in our not not here in the pages for
  • 00:04:26 example on the bookings page we are of
  • 00:04:28 course making HTTP requests to our
  • 00:04:30 back-end and I'm doing this year by
  • 00:04:32 sending a post request manually now as a
  • 00:04:35 side note you could of course use
  • 00:04:38 libraries for that you could use a polo
  • 00:04:40 client you could also set up the backend
  • 00:04:43 with Apollo server and I'm just doing
  • 00:04:45 this all without libraries to show you
  • 00:04:48 what's happening under the hood
  • 00:04:49 that's the only reason definitely use
  • 00:04:51 libraries for your projects I just want
  • 00:04:54 to show you everything that is happening
  • 00:04:56 now when you are sending your requests
  • 00:04:59 like this with your own post requests
  • 00:05:02 well then in cases where you also add
  • 00:05:05 data like here where we inject some
  • 00:05:09 dynamic information into our request
  • 00:05:12 definition there is a better way of
  • 00:05:14 doing that instead of injecting it here
  • 00:05:17 which of course works fine it is
  • 00:05:19 recommended to not inject it here but
  • 00:05:22 instead add a reference in your graph
  • 00:05:25 fuel crew which starts with a dollar
  • 00:05:26 sign and then any name you want for
  • 00:05:29 example booking ID but you could name
  • 00:05:32 this book ID or just ID whatever you
  • 00:05:35 want and I'll use ID so that you are not
  • 00:05:38 confusing it with this booking ID and
  • 00:05:40 name here but you can use any name you
  • 00:05:42 want here the dollar sign is important
  • 00:05:44 though now that alone will not do the
  • 00:05:46 trick though you also now have to give
  • 00:05:48 your query or mutation in this case here
  • 00:05:51 a name and I'll name it cancel booking
  • 00:05:56 that name is all's up to you and here
  • 00:05:58 you define which kind of data will be
  • 00:06:00 used inside of your mutation there you
  • 00:06:03 should repeat that argument you're using
  • 00:06:06 here so dollar sign ID in my case and if
  • 00:06:08 you named it differently you have to
  • 00:06:10 name it differently up here as well and
  • 00:06:12 then you also assign a type here which
  • 00:06:15 in my case here is ID and this is
  • 00:06:17 required it must not be null so you
  • 00:06:20 might of course know that notation here
  • 00:06:22 especially the type notation from the
  • 00:06:25 schema in the graph QL schema we also
  • 00:06:28 work with types like this and indeed we
  • 00:06:31 work with exactly the same types here
  • 00:06:33 now is that being named we're basically
  • 00:06:36 telling graph QL hey there will be a
  • 00:06:40 variable named ID which actually
  • 00:06:43 contains the dynamic value you're
  • 00:06:45 expecting here and now it's our job to
  • 00:06:48 pass in that variable now how does that
  • 00:06:50 work you simply pass more into your
  • 00:06:54 request body please note that thus far
  • 00:06:56 we only have that query field and maybe
  • 00:06:59 you wondered why we need that why we
  • 00:07:01 don't just send that string as a request
  • 00:07:04 body well we need it because actually
  • 00:07:06 we're not limited to sending just to
  • 00:07:08 query you can add another field in this
  • 00:07:11 request body object here which should be
  • 00:07:14 named variables we're
  • 00:07:16 is an average javascript object where
  • 00:07:18 you now have key value pairs where your
  • 00:07:21 keys have to match the names you have in
  • 00:07:24 here without the dollar sign and the
  • 00:07:26 values well are the values you want to
  • 00:07:28 pass in so here I add ID as a variable
  • 00:07:31 and then I set this equal to booking ID
  • 00:07:34 and now this will send a request to the
  • 00:07:36 backend which can be parsed by the
  • 00:07:38 backend because our Express graph QL
  • 00:07:40 server will in the end parse the
  • 00:07:42 incoming request for a query field and
  • 00:07:44 for a variables field and it will then
  • 00:07:47 be merged together on the back end so
  • 00:07:49 this ID here will basically be added
  • 00:07:52 into this query expression here on the
  • 00:07:55 back end you could say so therefore now
  • 00:07:57 if I save this we should still be able
  • 00:08:00 to cancel a booking if I do quickly log
  • 00:08:03 in again go to bookings and I can cancel
  • 00:08:08 your that looks good it is gone and if I
  • 00:08:11 lock big back in just to check yeah it
  • 00:08:15 really is gone so canceling still works
  • 00:08:18 and this is how you can add variables or
  • 00:08:20 how you should add variables so any
  • 00:08:23 dynamic values into your graphical
  • 00:08:25 queries so let's have a look at our
  • 00:08:27 queries we have here for fetching
  • 00:08:29 bookings I'm not passing any dynamic
  • 00:08:32 data so no need to add variables here
  • 00:08:34 and therefore I think we're done with
  • 00:08:36 the bookings but of course we got more
  • 00:08:38 variables here in off J's for example
  • 00:08:41 when I do login you see here we got
  • 00:08:44 email and password well we should
  • 00:08:46 replace that for example with dollar
  • 00:08:48 sign email and with dollar sign password
  • 00:08:52 please also note that I removed the
  • 00:08:53 quotation marks you don't need them
  • 00:08:55 anymore when using this syntax now we
  • 00:08:58 need to give this a name like create
  • 00:09:00 user whatever you want and I define that
  • 00:09:03 I'll have an email whoops dollar sign
  • 00:09:05 email variable in there which will be of
  • 00:09:07 type string and I'll have a dollar sign
  • 00:09:10 password variable in there which will
  • 00:09:12 also be of type string and both are
  • 00:09:14 required and must not be null and with
  • 00:09:18 that just as before we add this new
  • 00:09:20 variables field here have an object and
  • 00:09:23 there our email refers to the email
  • 00:09:27 variable we get so this constant
  • 00:09:30 basically which we extract and we'll do
  • 00:09:32 the same for password so here I also
  • 00:09:33 pass in password and now just to make
  • 00:09:36 sure this is not confusing email here in
  • 00:09:40 front of the colon has to match the name
  • 00:09:43 you chose here in your graph QL query so
  • 00:09:46 with the dollar sign but down there
  • 00:09:48 without the dollar sign and email on the
  • 00:09:51 right side of that colon
  • 00:09:53 that simply refers to the value we want
  • 00:09:55 to pass in which here is our email
  • 00:09:57 constant it's the same for password with
  • 00:09:59 the password constant so now we have
  • 00:10:02 that query using our variables now for
  • 00:10:06 creating a user after logging in excuse
  • 00:10:08 me it's the same now this is a query not
  • 00:10:10 a mutation but still you can give it a
  • 00:10:12 name and there I want to have an email
  • 00:10:14 which is of type string and a required
  • 00:10:16 string I'll also have a password which
  • 00:10:19 is also required string and then here we
  • 00:10:22 use dollar sign email and here we use
  • 00:10:26 dollar sign password and just as before
  • 00:10:30 we should now add our variables object
  • 00:10:33 and set email to email and password –
  • 00:10:36 password so essentially the same we did
  • 00:10:39 for logging in now we got to that create
  • 00:10:42 user and login query adjusted let's
  • 00:10:45 quickly give it a try as this reloads
  • 00:10:48 let's try logging in that looks good and
  • 00:10:52 if I log out here and I authenticate
  • 00:10:55 again or and
  • 00:10:56 this time I try to create a new user
  • 00:10:58 with test free at test com now I'm
  • 00:11:04 getting an error here actually let's
  • 00:11:07 quickly see what's wrong here user
  • 00:11:13 exists already well okay now let's try
  • 00:11:16 an email that shouldn't exist yeah that
  • 00:11:20 looks better I got back a response that
  • 00:11:22 indicates that this succeeded and
  • 00:11:24 therefore now if I switch to login I can
  • 00:11:28 log in with that data so this now works
  • 00:11:31 let's see what else we can change that
  • 00:11:34 of course would be in the events J's
  • 00:11:36 file and in here for fetching events we
  • 00:11:39 leave that as it is because we're not
  • 00:11:41 passing in any dynamic data but
  • 00:11:43 up here we got a query a mutation for
  • 00:11:46 creating an event where we do pass in
  • 00:11:48 dynamic data so here we have a title a
  • 00:11:51 description a price and a date obviously
  • 00:11:54 that is a good scenario for replacing
  • 00:11:58 that so dollar sign title dollar sign
  • 00:12:01 desk for description dollar sign price
  • 00:12:06 and dollar sign date and with that
  • 00:12:11 changed here in the query string let's
  • 00:12:13 give this mutation a name create event
  • 00:12:16 for example and let's set up our data in
  • 00:12:19 there so we got dollar sign title and
  • 00:12:22 that should be a string dollar sign desk
  • 00:12:24 should definitely also be a string and
  • 00:12:26 both must not be null now for price and
  • 00:12:29 date in case you're not sure you can
  • 00:12:31 always check the schema and there you
  • 00:12:33 see that for a create event we are
  • 00:12:35 expecting event input and event input
  • 00:12:38 has a price which is a float and date
  • 00:12:40 which is a string so we should use these
  • 00:12:42 exact same types here so dollar sign
  • 00:12:45 price will be a float here a non null
  • 00:12:48 float and then here date is a string
  • 00:12:51 also not null and as before now we just
  • 00:12:55 have to add our variables field here an
  • 00:12:58 object where I set the title equal to
  • 00:13:01 title and with the title on the right
  • 00:13:04 side of the colon I'm referring to my
  • 00:13:06 title constant I'm extracting here and
  • 00:13:09 I'll do the same for price date and
  • 00:13:11 description so desc
  • 00:13:14 and here it should be desk because here
  • 00:13:16 I'm referring to the name I set up there
  • 00:13:18 in my query string desk will refer to
  • 00:13:21 description here price will refer to
  • 00:13:26 price and then last but not least I got
  • 00:13:30 the yeah the date which will refer to
  • 00:13:33 date so – the date constant up here with
  • 00:13:38 that this query is adjusted now as I
  • 00:13:40 mentioned for fetching events we don't
  • 00:13:42 need to adjust anything here for booking
  • 00:13:45 an event we do though let me cut this
  • 00:13:48 and replace that with dollar sign ID
  • 00:13:51 maybe and then here I have booked event
  • 00:13:54 as a name dollars
  • 00:13:57 an ID here will be an ID and now again
  • 00:14:01 we should pass it in with variables
  • 00:14:03 whoops we have our ID here and now I use
  • 00:14:07 a debt expression which I previously
  • 00:14:09 injected into the template literal so
  • 00:14:14 these are all the queries here let's
  • 00:14:16 give them a try here are the events so
  • 00:14:23 loading de Vence works which is good
  • 00:14:24 because we changed nothing there let me
  • 00:14:26 login and now let me try to book this
  • 00:14:30 event here I think it works it's the
  • 00:14:34 snow walk and we do see it here indeed
  • 00:14:37 canceling also still works let's try
  • 00:14:39 creating a new event does this work for
  • 00:14:45 199 let's pick a date here this one 14
  • 00:14:54 20 it should work and confirm this and
  • 00:14:59 this looks pretty good to me here is it
  • 00:15:01 does this work let's reload it's still
  • 00:15:03 there we can view the details and of
  • 00:15:06 course now we can also try to book that
  • 00:15:09 with an hour user so let's sign in with
  • 00:15:12 that user and let's book our newly
  • 00:15:15 created event here and we see it here
  • 00:15:18 under bookings so that looks pretty good
  • 00:15:21 to me
  • 00:15:22 this is the other refinement I wanted to
  • 00:15:25 add here now obviously you can refine
  • 00:15:28 way more on the sap especially here in
  • 00:15:30 the front-end you could add logic to
  • 00:15:32 store the token and check its validity
  • 00:15:35 when the app restarts to keep the user
  • 00:15:37 logged in you can show more helpful
  • 00:15:40 error messages when you're trying to
  • 00:15:42 create a user which exists already and
  • 00:15:44 these are all things you can definitely
  • 00:15:46 do but they're not really what I want to
  • 00:15:47 focus on here in this series because
  • 00:15:49 it's not so much about react but more
  • 00:15:51 about this basic graph QL API we built
  • 00:15:54 and therefore we're almost done now
  • 00:15:58 what's missing is of course the charts I
  • 00:16:00 promise to you and for that we will work
  • 00:16:03 towards that goal in the next videos
  • 00:16:05 hopefully see you there and I hope you
  • 00:16:07 like the serious thus far bye