#Angular Router Guards Pt.1: CanActivate vs CanActivateChild (2021)
Aug 15, 2023
#Angular Router Guards Pt.1: CanActivate vs CanActivateChild (2021)
Angular Router Guards are very powerful feature which gives you control over access to some certain route. In this video tutorial we will have a look at 2 of available routes: CanActivate and CanActivateChild. We will see use-cases for both of them and figure out how to properly choose between them. As a bonus part I will show you a design pattern called “Component-Less Route”. Thanks for your attention and enjoy watching ;) 📣 Become a Pro in Angular Material Theming (Advanced Workshop) 📣https://bit.ly/angular-material-themi … ✅ Use 10%-off coupon code: YOUTUBE_DISCOUNT (Only 2 coupons left) 📣 Blazing fast GraphQL Backend just in 1 Day with Hasura Engine 📣https://bit.ly/complete-hasura-course ✅ 20%-off coupon code: HASURA-EASY-START 00:00:00 - Intro; 00:00:55 - Project Overview; 00:04:40 - Implementation of CanActivate Guard; 00:11:25 - Restrictions of CanActivate Guard; 00:16:11 - CanActivateChild Guard in Action; 00:18:26 - Component-Less Route Pattern; 00:24:15 - Outro; 🔗 Link to the source code on GitHub:https://github.com/DMezhenskyi/angula … #angularrouter #canactivate #canactivatechild #webdevelopment #angulartip #frontend
Content
4.08 -> Hi everyone! My name is Dmytro Mezhenskyi
and in this video we will try to figure out
9.6 -> what the difference between guard CanActivate and
CanActivateChild in Angular Router. We will see
17.04 -> different use cases and in the very end of the
video i will show you one interesting pattern
22.48 -> so stay here and before we start i would like to
remind you that i have a couple of video courses
29.36 -> first one about Graphql engine called Hasura which
allows you to turn your database into real-time
36.56 -> and performant Graphql backend and the second
one about the angular material theming in this
43.52 -> workshop you will figure out how to properly
theme your components your application and
49.52 -> things like that the links will be in the video
description check this out and let's move forward
55.84 -> okay let's have a look at this application i
prepared for this tutorial and you can see that we
63.44 -> have the toolbar with two menu items and we have
some text which indicates that we are on the home
73.28 -> page and we can jump also to admin page which is
secured admin area and this secured admin area has
82.88 -> a few actions like add user and add product and if
i click on this button add user i see the form in
91.92 -> order to add some user and if i click add product
i will see the appropriate form for product
101.2 -> so as you can see very simple application
and now let's have a look at the source code
108.32 -> as you can see here this is the very simple
angular app inside the app component we have the
117.04 -> map toolbar and we also have the main tech and
here inside i use a router outlet in order to
126.32 -> render components which associated with some
certain uh road and um yeah nothing interesting
136.32 -> here this is just a simple um app component let's
have a look at the app rolling uh how it looks
145.76 -> right now and you can see that we have the empty
path where we render home component this is
153.2 -> what you have seen right there and we have
a bit more sophisticated route which is
160.48 -> admin and we have like on the road admin we
render the welcome component which is also very
169.28 -> very simple we will have a look it in a second
and it has two children add user and add product
177.52 -> now let's go to the admin model and like check
one by one how it looks like so we start from
185.84 -> the welcome component here when we navigate to
the admin we see this component which is which
195.36 -> represents our welcome component and inside ts
file we have nothing but here we have another
203.52 -> our router outlet where we're going to render
child roles and it's associated components right
210.88 -> here and this is just a section with actions and
some h1 header so this is basically this part what
221.6 -> you can see right here and then if we navigate
to add user uh we will see that it has just a
231.68 -> simple form inside ts file we have also very basic
form builder and very similar thing we have done
241.52 -> for also add product component uh yeah this is
how it looks like and it's worth to mention that
250.72 -> we have also out where leaves only one service
and this is authentication service so far it has
259.12 -> um like mocked functionality we don't go to
the server to check user authentication or we
267.12 -> don't check any jwt tokens whatever it's just
smoked it's just for this particular example
275.36 -> so i hope everything is clear for
now and as you may notice that
282.8 -> we have access to admin for anyone we don't have
any custom logic which protects our route from
292.72 -> unauthorized users and we're going to fix it and
we will fix it with the connectivity card which
301.2 -> you most probably all know but for those who is
not aware it might be useful so let's go to the
310.72 -> uh code and i'm going to create the can activate
uh road guard first and i will be using the
323.68 -> extension you're always asking me how cold this
extension it's called nx console which allows you
330.88 -> to generate um components and this is how it
uh looks like an x console once you installed
339.84 -> you will be able to click on some folder whatever
and you will get this ng generate ui and here you
348.8 -> can pick that you want to generate guard so let's
do it and i will name it like authentication
363.92 -> then we have to pick which one guard guard
type it is so i will pick can activate
371.12 -> the rest we will check maybe in some next videos
uh but for now we care only about can activate
381.28 -> then i say that it should be rendered under the
auth folder and then i take skip tests because
388.72 -> i don't need tests for this particular case
because it's just example and then i just click
395.76 -> run and it should generate authentication guard
and let's have a look inside what do we have so
402.96 -> as you can see that this is just uh service
yeah you can see injectable provided in root
410.48 -> and the one difference is that it implements
can activate it implements can activate because
417.84 -> this service which we're going to use are the
authentication card should always have this can
425.28 -> activate method and implements kind of forces us
to implement some logic there here you can see
432.08 -> that it takes two parameters this can activate
method you get activated road snapshot and
440 -> you get the rotors the whole rotor state snapshot
and you should return it the observable of boolean
447.84 -> or url tree if you want to redirect redirect user
to some another road or you can also return the
456.96 -> promise with the same like boolean or url tree or
it can be just boolean or it can be just oral tree
465.44 -> so far it returns true so always everyone can
access the the road which is protected with this
474.32 -> authentication guard but let's make it a little
bit smarter so i'm going to inject uh inside the
482.64 -> constructor my auth service so i will call
it auth here we go and here i will say that
495.44 -> please check is logged in and then i will use pipe
and inside pipe i will use map and i say that if
508.64 -> so i will get i hear the result or what return of
this is logged in so i will get some boolean and i
518.32 -> will name it like if is authenticated or let's say
is logged in right and i either return logged in
529.28 -> if it's true or if it's not true i want to return
url 3 in order to redirect user to some particular
538.16 -> role let's say on the home page and in order to
build this url 3 i need to inject also router
547.92 -> here we go and here i say that please uh create
oral 3 3 for empty road so it means for home page
564.32 -> right and this is what we're going to
return but we have to also connect this
571.2 -> authentication guard with some particular road
correct and in order to do this we go to our app
580.72 -> routing and i say that the admin road should be
activated so i'm using this keyword can activate
590.88 -> for this and inside the array i say that it should
put this guard so oops i forgot comma here so
601.68 -> yeah now if we attach the authentication guard to
this road it will check first uh our can activate
612.96 -> method if it returns true then it instantiate
this component we defined here otherwise
621.84 -> uh either happens nothing if we return false
or it will be red we will be redirected to the
630.4 -> url we defined inside world world tree
and if we save it let me check if i say
638.08 -> yeah looks fine and you can see that now it works
fine because we return um hard coded true value
648.08 -> now let's try to return false just to emulate that
user was logged out or something like this and you
657.52 -> can see that we were immediately redirected to
their home page i tried to navigate to the admin
665.04 -> but it doesn't work because we protected the
admin so can activate takes the routing you are
672.88 -> applying to and everything all children
which calls after this admin road they
680.96 -> will be protected by this authentication guard
okay so let's maybe revert it back to true
691.68 -> and let's uh console lock something here inside
our can activate so i say that like console.log
703.84 -> like i'm checking out okay and now let's try
to go back to our web app and open the console
715.04 -> here we go i will zoom it in and see
the interesting thing when we reload
722.56 -> we see that i'm checking out was executed that's
fine however if we go to add user and then we
732.72 -> go to the add product we see that it was not
involved as well but sometimes we would need
740.8 -> to have some additional check every time we
activate some child role as example we have
748.08 -> different rights for admin someone has
right permissions someone has only read
754.32 -> permissions and every time we activate a child
road we want to check permissions all right and
764.4 -> you can also implement this by using
connectivate and let's do it so i will
772.64 -> again use ng generate and we say that we
need guard and i will name it per missions
784.96 -> and we also like do it like can activate okay
here we go let me just delete the test file
797.92 -> and i will move it next to our authentication
okay and here in our service let's add maybe
808.4 -> some method like has permissions okay and it
returns observable of true as example for now
822 -> good and inside our permission we would
do something similar what we have done for
829.44 -> our authentication guard so i inject
service and then i would need to check
839.92 -> if this house has permissions then we can like
enter this road and we can save it actually
851.04 -> and copy this or i will remove also on this route
because it's we are not using them and then i
860.56 -> will go to my app routing and i have to like can
activate and call permission card against every
870.88 -> roll so i can copy this here as well and i just
paste it and we have to import this of course
881.52 -> here we go so if we reload and then i
navigate between we have to add also
889.44 -> console.log here in order to see if
it was executed so console log like
897.2 -> i'm checking permissions okay and now
you see that we activated admins so
904.4 -> our out guard was involved and then we also
do a permissions check for add user component
914.64 -> and if we go to add product you see that
permission check again has been involved right
922.32 -> and every time we try to activate some certain uh
road or component that can activate will be called
931.6 -> also for child but here we have only two children
yeah but imagine the real live app has tons of
942.72 -> child components you can have i don't
know dozens or even hundreds uh child
949.6 -> children's four year old and you have to add
manually this permission guard for every child and
958.24 -> this is very error prone because you just simply
can forget to edit and to not underestimate it
966.96 -> really it sometimes happens
even with experienced developers
971.12 -> so uh the better way to handle this thing would
be exactly can activate children and the thing you
981.52 -> have to do is just slightly modify our permissions
guard and instead of implementing can activate
990.96 -> interface you have to implement can
activate child and here you have to just
1000.24 -> implement slightly different interface
so it called connectivate child and
1007.84 -> basically we can copy everything from can activate
here and paste it in place of this throw error and
1018.4 -> you can see this is very similar to what we had
with connective 8 we have just a child rolled so
1025.76 -> this is the road which we're going to activate and
the state of the rotor state of the rotor state so
1034.32 -> we are not going to use it so i will remove it
but just to let you know that we have such um
1041.28 -> such arguments good uh don't we
have any errors looks like no
1048.96 -> and now we have i use this permission guard in
our routing but we don't use this can activate
1058 -> anymore we use can activate child and here
inside array i will provide our permission
1067.04 -> guard and now i don't need it anymore for my
my children and if i save it we should see
1076.8 -> the same behavior i will go to admin and navigate
between childs on and every time i activate child
1086.72 -> this permission card was executed so once
you add some new child to it you should not
1095.36 -> care about providing the permission guard
anymore because by default everything under
1102.32 -> this road will be protected with a permission
guard and now as a small bonus let me show you
1110.08 -> the pattern called componentlessroad and it
looks like this so we we just temporarily copy
1120.88 -> this roads here and we introduce the new road
and the path for this road will be empty string
1129.92 -> and here we don't define any component that's
why it called componentless but we called
1138.56 -> here children and already here inside the children
we paste the roads we copied before so it looks
1149.68 -> like this right now so we have kind of middleware
road which is which has empty string and
1159.44 -> in our case it me it like it doesn't change
anything for us because uh it still will be
1167.28 -> mapped as admin add user because here is empty
string so yeah we do admin then technically should
1174.56 -> be some rolled but because it's empty they will be
mapped the next one add user so if we save it like
1182.16 -> this nothing has been changed everything works uh
fine but what the benefit then from this pattern
1191.04 -> well getting back to permissions you can see that
we have add users and add product which means that
1199.12 -> this is something which is allowed to do only
for admins who has write permissions and you can
1206.88 -> see how we structured our route so we have admin
and there it goes add user and then we have add
1214.96 -> product yeah they kind of on the same level the
child of admin wrote but what if we want to have
1224.72 -> road called list as example which is
also on the same level with the admin
1231.2 -> but we want to have this road available for any
kind of admins so without this pattern if we would
1241.6 -> revert it we would need to add this list next to
add product and add user and our permissions guard
1253.12 -> which check this strict rules would apply also
for this new router which we could name list
1265.2 -> you know what i mean but we don't want to apply
this permission guard to this particular road
1274.24 -> we don't want to have it that's why we're using
this middleware road in order to group these two
1283.2 -> roads under the one guard and in our case it will
be can activate child permissions guard yeah so we
1298.8 -> protect everything which is child for
this pass and technically to admin
1307.36 -> with this permission guard but if we
want to introduce on the same level
1313.28 -> the another component which should be
accessible without any check we can do it by
1321.68 -> adding it next to this middleware role so
here somewhere i will introduce the path
1331.04 -> with empty string or not empty
string i will call it list
1337.92 -> because i want to have admin slash
list and then render some component
1344.8 -> which we have to create so let's maybe where
we're going to create under the admin i will
1354.08 -> generate or let's generate
material table so i call it list
1365.52 -> i declared under admin
1371.12 -> okay looks good i run it
1376.56 -> so we can see that the list
was generated so now we can
1384.24 -> go to app routing and import the list component
here we go and now we can see that ah we have
1394.88 -> to add the action to this list right so okay
here is our actions so i will duplicate it
1404.96 -> and then let's say show list i will name it like
this and here the router link will lead to list
1417.12 -> here we go now we see the new action you can see
that permission checks happen to end user and add
1424.56 -> product which are scoped by our componentless
compo rotor sorry right these guys but
1434.56 -> if we navigate to the list you will see that this
check was not executed anymore however we have it
1442.8 -> on the same level with the add product and add
user so this is where this componentless pattern
1452.48 -> componentless router pattern might be useful all
right guys that was it thank you for attention i
1458.8 -> hope you enjoyed it and don't forget that this is
just a first part of a video series about angular
1466.96 -> router guards in next video we'll have a look at
the rest of them and if you like what i'm doing
1473.04 -> please share this video with your colleagues
hit thumbs up and of course don't forget to
1479.2 -> leave your feedback in the comment section and i
wish you productive week and see you in two weeks
Source: https://www.youtube.com/watch?v=NxidP4I9EHE