Coding

#14 Using the Token | Build a Complete App with GraphQL, Node.js, MongoDB and React.js

  • 00:00:01 hi everyone so we are able to now send
  • 00:00:05 our sign up and login requests from the
  • 00:00:07 react app to the backend but we're not
  • 00:00:10 doing anything with that token and with
  • 00:00:12 that data there after and one of the
  • 00:00:15 important reasons for not doing anything
  • 00:00:17 is of course that we have no logic to
  • 00:00:19 create events or do booking sends on so
  • 00:00:22 we'll take our next steps towards that
  • 00:00:24 goal and make sure that our UI changes a
  • 00:00:27 little bit when we are logged in and
  • 00:00:28 when we are not logged in in this video
  • 00:00:34 so let's start with DUI maybe and how
  • 00:00:38 can we determine whether we are locked
  • 00:00:40 in or not well we got this token which
  • 00:00:43 we get when we log in right so let's use
  • 00:00:45 that token and store it somewhere in our
  • 00:00:49 application and change other parts of
  • 00:00:51 DUI based on that now in off J s here we
  • 00:00:57 do get our token effectively here in the
  • 00:01:00 van block after logging and not for
  • 00:01:02 signing up but for logging in so in the
  • 00:01:05 end our goal will be to store the token
  • 00:01:07 somewhere so that we can use it in other
  • 00:01:10 parts of the application – like in our
  • 00:01:12 main navigation which mean the end send
  • 00:01:14 up here set up here in AB Jas there now
  • 00:01:18 how can we get data from inside a route
  • 00:01:20 like our off route where we effectively
  • 00:01:23 gets the token into that main navigation
  • 00:01:26 well we could use read acts for that but
  • 00:01:29 we can also use something which is
  • 00:01:30 built-in to react which is the context
  • 00:01:33 API and that is exactly what I want to
  • 00:01:36 use here I'll create a new folder
  • 00:01:38 context here and in there I'll add my
  • 00:01:41 off context dot JS file now how do we
  • 00:01:46 create this context and how does it work
  • 00:01:48 well context in the end is something
  • 00:01:50 which you can think of as a storage we
  • 00:01:53 can set up in the react app which we can
  • 00:01:56 then access from anywhere in our
  • 00:01:58 component tree so instead of passing
  • 00:02:01 props around manually across all levels
  • 00:02:04 we can basically use the context as a
  • 00:02:06 central storage to bypass our entire
  • 00:02:09 elements or a component tree and just
  • 00:02:12 get the data in the places where we need
  • 00:02:14 them therefore here I will export a
  • 00:02:18 default react create context result
  • 00:02:22 which is basically an context object and
  • 00:02:24 of course for that to be available I
  • 00:02:27 need to import react from react now
  • 00:02:30 create context here then also takes a
  • 00:02:32 default value and this could also just
  • 00:02:35 be a number or could be a string but
  • 00:02:39 here it will be a JavaScript object and
  • 00:02:41 in there I'll have a token field which
  • 00:02:44 by default will be an empty string or
  • 00:02:48 null even and I will have a login method
  • 00:02:52 which here is just an empty method
  • 00:02:54 that's that does nothing but adding it
  • 00:02:56 here will help us with Auto completion
  • 00:02:58 later and I'll do the same for logout so
  • 00:03:01 I got a token a login and a logout and
  • 00:03:04 actually I also want to have my user ID
  • 00:03:07 in here which is also null initially now
  • 00:03:11 we export this contexts now we can
  • 00:03:13 import it into our files and we want to
  • 00:03:16 import into that file which is the the
  • 00:03:19 highest at the highest level of where we
  • 00:03:22 wanna use that context we can then
  • 00:03:25 access the context from our all child
  • 00:03:27 components but not from any higher
  • 00:03:30 components and my guess that would be
  • 00:03:32 the app chess and I want to wrap the
  • 00:03:34 main navigation and the entire main
  • 00:03:36 block here with the same context so that
  • 00:03:38 anywhere in these wrapped elements we
  • 00:03:41 can access that context now what do I
  • 00:03:43 mean with rap well let's first of all
  • 00:03:45 import our context and then it will be
  • 00:03:48 clearer I'll have my off context and you
  • 00:03:51 can name this however you want because
  • 00:03:53 it's a default export and I'll get this
  • 00:03:56 from my context folder and there the off
  • 00:04:00 context file and let's now use that like
  • 00:04:07 a normal JSX element but actually not
  • 00:04:10 off context itself but it does have a
  • 00:04:12 consumer and the provider and here we
  • 00:04:15 need to provider and now we wrap this
  • 00:04:18 around all elements where we want to be
  • 00:04:20 able to use that context so in my case
  • 00:04:23 that would be these elements so now
  • 00:04:27 anywhere in there and in their children
  • 00:04:29 we can now access this context and we
  • 00:04:31 can do this conveniently for example in
  • 00:04:33 object since it's a class-based
  • 00:04:36 component with this static context type
  • 00:04:39 we can add static context type here so a
  • 00:04:47 static property and set this equal to
  • 00:04:50 and now import our context again of
  • 00:04:52 context from context off context we can
  • 00:04:58 now set this property equal to off
  • 00:05:00 context and bhai
  • 00:05:01 the scenes react will make the
  • 00:05:03 connection and will now give us access
  • 00:05:05 to our context data so basically to this
  • 00:05:09 default data data right now in this
  • 00:05:14 context property so now anywhere in here
  • 00:05:16 we can access this context for example
  • 00:05:20 here in this then block here I want to
  • 00:05:23 check if this state is login so if we
  • 00:05:26 are logging in then I know that this
  • 00:05:28 response will have a token alternatively
  • 00:05:31 I can also of course check rest data if
  • 00:05:33 it has a token property because we know
  • 00:05:35 it will have a data field a login field
  • 00:05:37 and a token field so we could say rest
  • 00:05:40 data does it have a data and then a
  • 00:05:42 login and a token field if it does have
  • 00:05:45 we know we can set this we can now
  • 00:05:47 access this context which again is now a
  • 00:05:50 property given to us by react which will
  • 00:05:53 have essentially everything are off
  • 00:05:56 context data has so here we set this
  • 00:05:59 equal to off context in off context we
  • 00:06:01 have login logout token user ID so now I
  • 00:06:05 can call down there this context login
  • 00:06:12 and now let's say there I wanna forward
  • 00:06:15 rests data data login token and rest
  • 00:06:19 data data login user ID one of forward
  • 00:06:23 these two fields here token and user ID
  • 00:06:27 maybe also our rest data data login
  • 00:06:31 token expiration field so basically all
  • 00:06:34 three fields are now forwarded here and
  • 00:06:37 of course you would be correct if you
  • 00:06:39 now think what would this do because in
  • 00:06:42 our context these methods don't do
  • 00:06:46 anything well we can add the arguments
  • 00:06:50 we expect to get so the arguments in
  • 00:06:52 passing here token user ID and token
  • 00:06:54 expiration we can add it here user ID
  • 00:06:57 token expiration but of course we still
  • 00:07:00 don't do anything and we won't write the
  • 00:07:02 logic for the login function here I just
  • 00:07:04 do this so that I can get better Auto
  • 00:07:07 completion and IDE support later what
  • 00:07:10 I'm really interested in is the place
  • 00:07:13 where we initialize this context
  • 00:07:15 in the app JS file because provider here
  • 00:07:18 also takes a value and this value allows
  • 00:07:22 us to set the current value of this
  • 00:07:25 context which is then distribute down to
  • 00:07:27 all the children who are interested now
  • 00:07:30 that means that here I can now set well
  • 00:07:34 all the values which this context has so
  • 00:07:37 all the fields which my off context here
  • 00:07:40 has so token user ID and the two methods
  • 00:07:43 can be set here now I will set token
  • 00:07:48 here to an empty string still order to
  • 00:07:50 null initially and it will set user ID
  • 00:07:55 here to now but I can now also bind my
  • 00:07:58 methods to methods which are add here
  • 00:08:00 and there I will add a login method
  • 00:08:03 which gets a token a user ID and token
  • 00:08:06 expiration and which then can do
  • 00:08:11 something with it
  • 00:08:11 oops let's write it as an arrow function
  • 00:08:14 and we can also add a logout method
  • 00:08:17 which right now doesn't do anything but
  • 00:08:18 which will soon do so and now we can
  • 00:08:21 bind the login field in our context
  • 00:08:25 value here to this login method and
  • 00:08:28 suddenly when we call log in from
  • 00:08:30 anywhere in our component tree it's this
  • 00:08:33 global login method which will be called
  • 00:08:35 in the same of course for a logout we
  • 00:08:38 can call this logout here
  • 00:08:40 now the interesting part is that we can
  • 00:08:43 now manage our good old State in this
  • 00:08:45 class here just as we always did totally
  • 00:08:49 unrelated to the context in general and
  • 00:08:51 there we can manage token set it to null
  • 00:08:55 and the user ID and set this to null for
  • 00:08:58 example and here in login in De Smet we
  • 00:09:03 can now call this set State and set
  • 00:09:06 whoops no login and set token to the
  • 00:09:09 token we get as an argument and the same
  • 00:09:11 for the user ID and I'll take care about
  • 00:09:13 the token expiration at a later point of
  • 00:09:15 time now this allows us to call
  • 00:09:18 something on our context and implicitly
  • 00:09:21 called this method which then in turn
  • 00:09:23 changes the state of this class and now
  • 00:09:26 we can use the same state to manipulate
  • 00:09:29 the
  • 00:09:29 context value which is then passed down
  • 00:09:31 to all children again so here we can set
  • 00:09:34 this token to this state token and the
  • 00:09:38 user ID to this state user ID I hope you
  • 00:09:42 can now see that circle of how we can
  • 00:09:44 now use this state management app j/s
  • 00:09:46 and make it globally available in all
  • 00:09:49 child components through the context and
  • 00:09:52 in logout we would call this set state
  • 00:09:55 and simply set token to null and user ID
  • 00:09:58 to null now with that we have a way of
  • 00:10:03 managing our data here now in main
  • 00:10:07 navigation which important is a child of
  • 00:10:10 our context provider we can access this
  • 00:10:13 context now this year is a functional
  • 00:10:18 component therefore this static context
  • 00:10:20 type thing won't work here but there
  • 00:10:24 won't be a problem because a we could of
  • 00:10:27 course pass our data with normal props
  • 00:10:29 in app tray s main navigation is a
  • 00:10:33 direct child's we could add a token or a
  • 00:10:36 is auth prop and pass that down and that
  • 00:10:38 would be a absolutely fine approach but
  • 00:10:41 B just to practice this context thing a
  • 00:10:43 bit more we can also just import our off
  • 00:10:47 context here whoops from context off
  • 00:10:54 context and use a different form of that
  • 00:10:58 API we can now use the consumer now
  • 00:11:02 consumer is also a JSX element and this
  • 00:11:07 actually then gives us a function which
  • 00:11:11 we call or which we pass as a child here
  • 00:11:15 and then this function result we return
  • 00:11:19 the JSX code which we actually want to
  • 00:11:21 render like this and now this function
  • 00:11:24 will receive our context value
  • 00:11:27 essentially that is how it works so here
  • 00:11:30 this context will have access to all
  • 00:11:32 these context fields we used before or
  • 00:11:34 like token and so on and therefore we
  • 00:11:36 can use that to for example only render
  • 00:11:38 this list item here authenticate if we
  • 00:11:41 can authenticate
  • 00:11:43 if we are not logged in only if it makes
  • 00:11:45 sense so we can use that syntax here and
  • 00:11:49 check context token and if that exists
  • 00:11:54 then we'll render this list item
  • 00:11:56 otherwise it will not be rendered and on
  • 00:11:59 the same page
  • 00:12:00 I will only render events in booking
  • 00:12:01 let's say if we are actually locked in
  • 00:12:07 or let me quickly check here on the back
  • 00:12:11 end I think we actually have an events
  • 00:12:14 route which we can use without being
  • 00:12:16 authenticated yes this one so actually
  • 00:12:19 I'll revert this events is always
  • 00:12:23 rendered but bookings is not so here
  • 00:12:27 bookings this will only be rendered if
  • 00:12:29 the token is set and here I have an
  • 00:12:32 error of fennekin is only rendered if it
  • 00:12:34 is not set so now I'm using that token
  • 00:12:37 here and if I save all of that now you
  • 00:12:41 already see we have authenticated events
  • 00:12:42 here if I do now login which should give
  • 00:12:45 us a token this changes now I'm still on
  • 00:12:48 the authentication page because I
  • 00:12:50 haven't added logic to redirect but this
  • 00:12:52 works that is great and if I reload will
  • 00:12:55 lose our state and therefore we'll use
  • 00:12:57 we lose the token and unlocked out again
  • 00:12:59 and we can persist the session by
  • 00:13:01 storing the token and local storage and
  • 00:13:03 so on but I'll not do this for now now
  • 00:13:05 of course it would be nice to get
  • 00:13:07 redirected as well and in general on App
  • 00:13:10 j/s we shouldn't be able to reach all
  • 00:13:13 the routes as a default and I don't want
  • 00:13:15 to redirect you off all the time only if
  • 00:13:18 I'm not authenticated the good thing is
  • 00:13:21 since we was routing here just as normal
  • 00:13:23 JSX elements and in-app J's we of course
  • 00:13:26 have access to state token we don't even
  • 00:13:28 need to context here we can of course
  • 00:13:30 render different route configurations
  • 00:13:33 based on our state so for example here
  • 00:13:37 this redirect route this only makes
  • 00:13:40 sense if we are not locked in so we'll
  • 00:13:43 check if this state token is set and
  • 00:13:45 only if it is not set indicated by that
  • 00:13:48 exclamation mark I will render this so
  • 00:13:50 this redirection will only kick in if we
  • 00:13:53 are not locked in now
  • 00:13:57 this off page here should only be
  • 00:13:59 reachable if this state token is not set
  • 00:14:04 of course otherwise we don't need to
  • 00:14:06 sign in because we already are and
  • 00:14:08 bookings here on the other hand should
  • 00:14:10 only be reachable if the token is set so
  • 00:14:13 just as the navigation item should only
  • 00:14:14 be rendered then the route should only
  • 00:14:16 be reachable in this case I also want to
  • 00:14:21 redirect the user from off to our events
  • 00:14:27 page let's say and also from slash to
  • 00:14:29 the events page if we are authenticated
  • 00:14:31 so I can duplicate these this
  • 00:14:33 redirection here and redirect from slash
  • 00:14:36 to events if we do have a token and also
  • 00:14:41 if we do have a token and of course
  • 00:14:42 therefore we can also theoretically
  • 00:14:45 group that but all do it one by one to
  • 00:14:47 make it really clear to understand so if
  • 00:14:49 we do have a token then I don't only
  • 00:14:52 want to redirect from slash to events
  • 00:14:54 but also from off to events let's say
  • 00:14:59 now let's save all of that and let's try
  • 00:15:04 this again let's log in here and I get
  • 00:15:07 redirected to the events page if I now
  • 00:15:10 try to go to slash nothing I get
  • 00:15:14 redirected to off because this reloads
  • 00:15:16 the page and therefore we get to
  • 00:15:20 dispatch again but we can see that once
  • 00:15:22 they do login will automatically get
  • 00:15:24 redirected to events as we should
  • 00:15:26 so our routing setup should not work the
  • 00:15:29 navigation bar now all's behaves
  • 00:15:31 correctly and therefore we are now
  • 00:15:33 starting to use our authentication data
  • 00:15:36 we are starting to use the token in the
  • 00:15:38 react application and that is a default
  • 00:15:41 pattern you would use for rendering the
  • 00:15:44 different parts depending on your user
  • 00:15:46 of indication state obviously you can't
  • 00:15:48 get more sophisticated than that but
  • 00:15:50 this is a great start now with that we
  • 00:15:54 got everything prepared to finally start
  • 00:15:56 working on the events page here and
  • 00:15:58 create events and render events and
  • 00:16:01 later all the book events in the next
  • 00:16:04 videos