Learn everything you need to know to use the Angular v6 router effectively. We start with the absolute basics, then move on to advanced concepts related to guards and resolvers https://angularfirebase.com/lessons/basics-angular-router/

- Router Docs https://angular.io/guide/router
- Lazy Loading Video https://youtu.be/8tBQI5grhbE
2024-02-04T07:31:43.725Z
nova-2
2-general-nova
2024-01-09.29447
30089e05-99d1-4376-b32e-c263170674af
653aafc8-fdcb-4e74-8ada-e27a71e54637
3ead82eefe57611b73583088ad1d6ef2979fce90b0c9e0f752c508c84b3bb665
67875a7f-c9c4-48a0-aa55-5bdb8a91c34a
deprecated
The router is one of the most powerful yet underutilized tools in Angular.
In addition to defining the URL structure for your app, it can also be used to control performance with lazy loading and help you write dry code with resolvers and guards.
Over the next few minutes you'll learn the basics of the Angular 6 router, plus few advanced techniques to preload data from Firebase and protect routes from unauthenticated users.
If you're new here, like and subscribe and grab the full write up from angularfirebase com.
The first thing we'll do to get started is generate a brand new Angular 6 app with the router flag.
That'll just give us a routing module automatically.
The first thing we'll wanna look at is the router outlet.
When you route to a component, it needs to be the child of some other component, which by default will be the app component and the root of the project.
So the outlet tells Angular where to render a component based on the URL that the user navigates to.
We can define our routes by going into the app routing module, and you'll see we have an array that's typed to the route's interface.
We can define each route in our application as an object, which will take a couple of configuration parameters.
The most basic use case would be to give your route a path and then route it to a specific component that you've generated.
Let's run n g generate component and we'll call this the home page.
Now the home page we could set up as the root path.
So we'll give that a path property of an empty string, then set the component option to the home component.
If we serve the app, we should see the home component rendered at the position of that router outlet.
Then notice how other content in the home component is still there such just the logo and the header.
That'd be a good place to put a nav bar and a footer and things that'll be present on every page.
That's a good start, but let's look at how we can navigate between multiple components by generating another one called animals.
Then we can import the component into our router module and set up another path and component property for this route.
When setting up hyperlinks in Angular, you don't use a normal h ref attribute like you would in a plain HTML page.
If you use a regular h ref, it'll cause your Angular to completely reload whenever it's clicked.
Instead we use the router link directive which tells Angular to treat this as an internal route, Then we simply pass it the path that we would normally route to with a link.
So now if we open up the app in the browser, we can click on this animals link And it will route us to the corresponding component.
So that takes care of your most basic use case, but what happens in the real world is generally you're pulling some information from a database, Then route to a specific ID to show more information about that item and you might have 1,000 or 1,000,000 of items in your database, so you can't just hard code all of those routes manually.
In this next section, we'll create a component called animal detail and we're going to make it a child route of animals.
You can create child routes That will be rendered inside of their parent by adding the children property to the parent route.
The children property itself will take an array of routes, So we just have a classic tree structure here.
We can define a dynamic URL parameter by putting a colon in front of whatever that parameter is.
This case, we're going to be looking up animals by their name in our database, so we'll set up colon name as that URL parameter.
Doing this means that can navigate to routes that will look like animal /elephant, animal/aardvark, or any other dynamic property that we pass to the second half of that URL segment.
You'll notice that we're dynamically generating a list of links that we're pulling from Firebase, so let me show you how I do that.
In In the parent component, I have an array of documents that I pulled from Firestore so I can loop over them asynchronously with n g 4 and the async pipe.
Then to build a link instead of passing it a string, I'll put brackets around the router link so we can pass it an expression, which in this case will be an array where each item in that array represents a URL segment.
So the first half of the segment is animals and the second half will be the animal's name.
Because this is a parent component, we'll need to tell the router where to render the child components, which we can do with a router outlet.
The The actual data in the database is just a collection of animals that have a few properties on each document.
Inside the parent component, we can retrieve documents with pretty much just a single line of code, we inject Firestore in the constructor and then reference these documents as the animals property And call value changes to listen to them as a real time observable.
In the child component, things are a little more tricky because we need to also listen to the change in the URL parameter to get the proper animal from the database.
The Angular router provides a service called activated route that allows us to listen to state changes in the router.
And then we'll also import the switch map operator from RxJS.
The important thing to understand here is that the component is only initialized once When the first route is navigated to, any child routes that are navigated to after that won't be called with NG on a net.
So what we wanna do here is use activated route to listen to changes in that URL parameter which is the animal's name, which we can do by calling route param map which returns an observable of the route parameters.
Then when a change occurs, we'll call switch map to switch to an observable of the actual animal data from buyer store.
Notice how we're calling params get name which matches the dynamic URL segment that we set in the router config.
So that returns the actual name of the animal which we can then pass on to Firestore to retrieve as a single document.
The last step is just to unwrap this document in the child component.
So we can do that with n g if animal async, Then set that as a template variable of animal and we'll just show some of the properties here in the components such as the name, bio, and image.
And you now have a structured router tree that will scale up to as many documents as you have saved in the database.
Up until this point, we've only been using router links to navigate, But you can also navigate directly from inside of the components TypeScript.
There are many cases where you just can't use a link click to navigate to a page and you wanna do it in a more dynamic way.
Maybe you have some really ugly animals in your database and you want to prompt the user to say yes before navigating.
In this case, we will import the router directly into our component.
We'll set up a click handler here that will first prompt the user to confirm that they wanna navigate to this page.
And then if they type in yes, we'll go ahead and navigate to that page manually with the router.
You can say router dot navigate and have it go to the array of URL segments that you point it to.
Back in the HTML, we can go ahead and remove the router link and replace it with the click event that will run our click handler whenever it's clicked.
So the key takeaway here is that you can navigate anywhere in your Angular code outside of the scope of a regular hyperlink.
Now I wanna go ahead and switch gears and show you a couple of things that are just super useful to do with the router.
Let's say you want to create a catch all route that will serve more or less as a 404 page if the user routes to a component that doesn't exist.
We can generate a new component to show the content and then we'll say path star star as a wildcard, and you wanna make sure that this route is the very last route in your tree.
Then if we go and type in some random URL into the browser, it's going to pull up our error component instead of just throwing a regular error to the end user.
Then another very common thing you might wanna do is instead of routing to a component, you might just want to redirect to a different route.
So let's say we have a common misspelling for animals, We can just redirect to the main animal's route.
When you set up a redirect route, you'll have to also add in the path match option.
Otherwise, Angular will throw an error.
If we go and navigate to this route on the browser, you'll see it redirects us to the animals component instead of bringing up the error component that we just created.
Another cool thing you can do is use the router link active directive to provide a CSS class whenever a certain route is active.
This makes it really easy to build out UI features that show the user which link they're currently on.
It expects a list of CSS classes on the right hand side.
So we'll define an active CSS class that will make the font bold and a different color.
Now you can see we get a clear UI change every time we go to a different link.
For the next few minutes, I wanna move a little beyond the basics and talk about guards to protect routes, create reusable code and preload data into your components.
A guard is just an Angular service that has some special interfaces that we can implement to do things with the router.
One of the most common use cases is to protect routes from unauthorized users.
Let's go ahead and run n g generate guard admin that will protect our routes from any non admin users.
The special interface we'll be using here is can activate, which will only activate this route if the guard resolves to true.
Let's go ahead and lock down our animals route by adding the can activate property with the admin guard.
If we go into the guard itself, you'll see that is decorated with injectable just like any other Angular service.
The only special thing is it has this can activate interface that gives us some information about the state of the route.
In order for the guard to work, we just need to return a Boolean, which can be a primitive or it can be an observable or promise.
If it's an observable, it's going to automatically subscribe for you.
So we'll go ahead and send an alert that says only admins allowed, and then we'll return false to block access to this route.
If we try to navigate to the animals page, you can see we get this alert and the component is never rendered.
But more often than not, you'll need to do this asynchronously by checking with some API if this user has authorization.
We can simulate this by setting up a timer of 1,000 milliseconds, Then we'll need to map the emitted value down to a boolean.
Then we can also use the tap operator to show an alert or this is a good place to navigate to a login page or something along those lines.
If we try to navigate to the page at this time, you'll see we get a one second delay, and then it finally blocks the route after this observable is resolved.
Can activate is a very powerful interface at your disposal, but there's also another one called resolve that can preload data into your route.
Do you remember earlier how in the animal detail component, we listened to the name parameter and then switch map to a different observable?
Well, maybe there's a better way we can do Imagine we wanted to preload this data on multiple different components.
We would have to write this code for each one of them.
Instead of repeating ourselves, Let's generate a guard called preload.
Instead of using the can activate interface, we'll use the resolve interface and you could strong type this as well, but for now, we'll just use any.
Then Then we'll change the method name to resolve and it's pretty similar to can activate, but instead we'll return the actual data that we want to be available when this route is navigated to.
And commonly, that's going to be an observable form because you're probably pulling this data from some external API.
In our case, we'll do it with Angular Firestore so we can inject that in the instructor.
Then the guard will have the actual parameter name available as a plain object, which we can retrieve with next dot parammap.getname.
Then we can just return the data as an observable, but we have to pipe in the first operator because Firebase returns real time stream, and we need this observable to complete in order for it to work properly.
Now we can just comment out all of our previous code, and instead, we'll just Define the animal as the data that is now available on this route when it's navigated to.
It's now available on the route data property, and then we can apply it to this route going back to our router config, then add the resolve property to our preload guard.
If we open up the app, it's going to work in exactly the same way as it did before.
But now, we've isolated this code in a reusable way that we can apply to multiple routes as needed.
Hopefully, that gives you a basic idea about how powerful the Angular router can be.
I'm gonna go ahead and wrap things up there.
If this video helped you, please like and subscribe.
And if you really wanna master the basics of Angular, consider becoming a pro member at angularfirebase.com.
You'll get access to a whole bunch of exclusive content designed to help you build and ship your app faster.
Thanks for watching and I'll talk to you soon.

Speaker 0: The router is one of the most powerful yet underutilized tools in Angular. In addition to defining the URL structure for your app, it can also be used to control performance with lazy loading and help you write dry code with resolvers and guards. Over the next few minutes you'll learn the basics of the Angular 6 router, plus few advanced techniques to preload data from Firebase and protect routes from unauthenticated users. If you're new here, like and subscribe and grab the full write up from angularfirebase com. The first thing we'll do to get started is generate a brand new Angular 6 app with the router flag.

That'll just give us a routing module automatically. The first thing we'll wanna look at is the router outlet. When you route to a component, it needs to be the child of some other component, which by default will be the app component and the root of the project. So the outlet tells Angular where to render a component based on the URL that the user navigates to. We can define our routes by going into the app routing module, and you'll see we have an array that's typed to the route's interface.

We can define each route in our application as an object, which will take a couple of configuration parameters. The most basic use case would be to give your route a path and then route it to a specific component that you've generated. Let's run n g generate component and we'll call this the home page. Now the home page we could set up as the root path. So we'll give that a path property of an empty string, then set the component option to the home component.

If we serve the app, we should see the home component rendered at the position of that router outlet. Then notice how other content in the home component is still there such just the logo and the header. That'd be a good place to put a nav bar and a footer and things that'll be present on every page. That's a good start, but let's look at how we can navigate between multiple components by generating another one called animals. Then we can import the component into our router module and set up another path and component property for this route.

When setting up hyperlinks in Angular, you don't use a normal h ref attribute like you would in a plain HTML page. If you use a regular h ref, it'll cause your Angular to completely reload whenever it's clicked. Instead we use the router link directive which tells Angular to treat this as an internal route, Then we simply pass it the path that we would normally route to with a link. So now if we open up the app in the browser, we can click on this animals link And it will route us to the corresponding component. So that takes care of your most basic use case, but what happens in the real world is generally you're pulling some information from a database, Then route to a specific ID to show more information about that item and you might have 1,000 or 1,000,000 of items in your database, so you can't just hard code all of those routes manually.

In this next section, we'll create a component called animal detail and we're going to make it a child route of animals. You can create child routes That will be rendered inside of their parent by adding the children property to the parent route. The children property itself will take an array of routes, So we just have a classic tree structure here. We can define a dynamic URL parameter by putting a colon in front of whatever that parameter is. This case, we're going to be looking up animals by their name in our database, so we'll set up colon name as that URL parameter.

Doing this means that can navigate to routes that will look like animal /elephant, animal/aardvark, or any other dynamic property that we pass to the second half of that URL segment. You'll notice that we're dynamically generating a list of links that we're pulling from Firebase, so let me show you how I do that. In In the parent component, I have an array of documents that I pulled from Firestore so I can loop over them asynchronously with n g 4 and the async pipe. Then to build a link instead of passing it a string, I'll put brackets around the router link so we can pass it an expression, which in this case will be an array where each item in that array represents a URL segment. So the first half of the segment is animals and the second half will be the animal's name.

Because this is a parent component, we'll need to tell the router where to render the child components, which we can do with a router outlet. The The actual data in the database is just a collection of animals that have a few properties on each document. Inside the parent component, we can retrieve documents with pretty much just a single line of code, we inject Firestore in the constructor and then reference these documents as the animals property And call value changes to listen to them as a real time observable. In the child component, things are a little more tricky because we need to also listen to the change in the URL parameter to get the proper animal from the database. The Angular router provides a service called activated route that allows us to listen to state changes in the router.

And then we'll also import the switch map operator from RxJS. The important thing to understand here is that the component is only initialized once When the first route is navigated to, any child routes that are navigated to after that won't be called with NG on a net. So what we wanna do here is use activated route to listen to changes in that URL parameter which is the animal's name, which we can do by calling route param map which returns an observable of the route parameters. Then when a change occurs, we'll call switch map to switch to an observable of the actual animal data from buyer store. Notice how we're calling params get name which matches the dynamic URL segment that we set in the router config.

So that returns the actual name of the animal which we can then pass on to Firestore to retrieve as a single document. The last step is just to unwrap this document in the child component. So we can do that with n g if animal async, Then set that as a template variable of animal and we'll just show some of the properties here in the components such as the name, bio, and image. And you now have a structured router tree that will scale up to as many documents as you have saved in the database. Up until this point, we've only been using router links to navigate, But you can also navigate directly from inside of the components TypeScript.

There are many cases where you just can't use a link click to navigate to a page and you wanna do it in a more dynamic way. Maybe you have some really ugly animals in your database and you want to prompt the user to say yes before navigating. In this case, we will import the router directly into our component. We'll set up a click handler here that will first prompt the user to confirm that they wanna navigate to this page. And then if they type in yes, we'll go ahead and navigate to that page manually with the router.

You can say router dot navigate and have it go to the array of URL segments that you point it to. Back in the HTML, we can go ahead and remove the router link and replace it with the click event that will run our click handler whenever it's clicked. So the key takeaway here is that you can navigate anywhere in your Angular code outside of the scope of a regular hyperlink. Now I wanna go ahead and switch gears and show you a couple of things that are just super useful to do with the router. Let's say you want to create a catch all route that will serve more or less as a 404 page if the user routes to a component that doesn't exist.

We can generate a new component to show the content and then we'll say path star star as a wildcard, and you wanna make sure that this route is the very last route in your tree. Then if we go and type in some random URL into the browser, it's going to pull up our error component instead of just throwing a regular error to the end user. Then another very common thing you might wanna do is instead of routing to a component, you might just want to redirect to a different route. So let's say we have a common misspelling for animals, We can just redirect to the main animal's route. When you set up a redirect route, you'll have to also add in the path match option.

Otherwise, Angular will throw an error. If we go and navigate to this route on the browser, you'll see it redirects us to the animals component instead of bringing up the error component that we just created. Another cool thing you can do is use the router link active directive to provide a CSS class whenever a certain route is active. This makes it really easy to build out UI features that show the user which link they're currently on. It expects a list of CSS classes on the right hand side.

So we'll define an active CSS class that will make the font bold and a different color. Now you can see we get a clear UI change every time we go to a different link. For the next few minutes, I wanna move a little beyond the basics and talk about guards to protect routes, create reusable code and preload data into your components. A guard is just an Angular service that has some special interfaces that we can implement to do things with the router. One of the most common use cases is to protect routes from unauthorized users.

Let's go ahead and run n g generate guard admin that will protect our routes from any non admin users. The special interface we'll be using here is can activate, which will only activate this route if the guard resolves to true. Let's go ahead and lock down our animals route by adding the can activate property with the admin guard. If we go into the guard itself, you'll see that is decorated with injectable just like any other Angular service. The only special thing is it has this can activate interface that gives us some information about the state of the route.

In order for the guard to work, we just need to return a Boolean, which can be a primitive or it can be an observable or promise. If it's an observable, it's going to automatically subscribe for you. So we'll go ahead and send an alert that says only admins allowed, and then we'll return false to block access to this route. If we try to navigate to the animals page, you can see we get this alert and the component is never rendered. But more often than not, you'll need to do this asynchronously by checking with some API if this user has authorization.

We can simulate this by setting up a timer of 1,000 milliseconds, Then we'll need to map the emitted value down to a boolean. Then we can also use the tap operator to show an alert or this is a good place to navigate to a login page or something along those lines. If we try to navigate to the page at this time, you'll see we get a one second delay, and then it finally blocks the route after this observable is resolved. Can activate is a very powerful interface at your disposal, but there's also another one called resolve that can preload data into your route. Do you remember earlier how in the animal detail component, we listened to the name parameter and then switch map to a different observable?

Well, maybe there's a better way we can do Imagine we wanted to preload this data on multiple different components. We would have to write this code for each one of them. Instead of repeating ourselves, Let's generate a guard called preload. Instead of using the can activate interface, we'll use the resolve interface and you could strong type this as well, but for now, we'll just use any. Then Then we'll change the method name to resolve and it's pretty similar to can activate, but instead we'll return the actual data that we want to be available when this route is navigated to.

And commonly, that's going to be an observable form because you're probably pulling this data from some external API. In our case, we'll do it with Angular Firestore so we can inject that in the instructor. Then the guard will have the actual parameter name available as a plain object, which we can retrieve with next dot parammap.getname. Then we can just return the data as an observable, but we have to pipe in the first operator because Firebase returns real time stream, and we need this observable to complete in order for it to work properly. Now we can just comment out all of our previous code, and instead, we'll just Define the animal as the data that is now available on this route when it's navigated to.

It's now available on the route data property, and then we can apply it to this route going back to our router config, then add the resolve property to our preload guard. If we open up the app, it's going to work in exactly the same way as it did before. But now, we've isolated this code in a reusable way that we can apply to multiple routes as needed. Hopefully, that gives you a basic idea about how powerful the Angular router can be. I'm gonna go ahead and wrap things up there.

If this video helped you, please like and subscribe. And if you really wanna master the basics of Angular, consider becoming a pro member at angularfirebase.com. You'll get access to a whole bunch of exclusive content designed to help you build and ship your app faster. Thanks for watching and I'll talk to you soon.
The router is one of the most powerful yet underutilized tools in Angular. In addition to defining the URL structure for your app, it can also be used to control performance with lazy loading and help you write dry code with resolvers and guards. Over the next few minutes you'll learn the basics of the Angular 6 router, plus few advanced techniques to preload data from Firebase and protect routes from unauthenticated users. If you're new here, like and subscribe and grab the full write up from angularfirebase com. The first thing we'll do to get started is generate a brand new Angular 6 app with the router flag. That'll just give us a routing module automatically. The first thing we'll wanna look at is the router outlet. When you route to a component, it needs to be the child of some other component, which by default will be the app component and the root of the project. So the outlet tells Angular where to render a component based on the URL that the user navigates to. We can define our routes by going into the app routing module, and you'll see we have an array that's typed to the route's interface. We can define each route in our application as an object, which will take a couple of configuration parameters. The most basic use case would be to give your route a path and then route it to a specific component that you've generated. Let's run n g generate component and we'll call this the home page. Now the home page we could set up as the root path. So we'll give that a path property of an empty string, then set the component option to the home component. If we serve the app, we should see the home component rendered at the position of that router outlet.
Then notice how other content in the home component is still there such just the logo and the header. That'd be a good place to put a nav bar and a footer and things that'll be present on every page. That's a good start, but let's look at how we can navigate between multiple components by generating another one called animals.
home improvement
Then we can import the component into our router module and set up another path and component property for this route. When setting up hyperlinks in Angular, you don't use a normal h ref attribute like you would in a plain HTML page. If you use a regular h ref, it'll cause your Angular to completely reload whenever it's clicked. Instead we use the router link directive which tells Angular to treat this as an internal route, Then we simply pass it the path that we would normally route to with a link.
So now if we open up the app in the browser, we can click on this animals link And it will route us to the corresponding component. So that takes care of your most basic use case, but what happens in the real world is generally you're pulling some information from a database, Then route to a specific ID to show more information about that item and you might have 1,000 or 1,000,000 of items in your database, so you can't just hard code all of those routes manually. In this next section, we'll create a component called animal detail and we're going to make it a child route of animals. You can create child routes That will be rendered inside of their parent by adding the children property to the parent route. The children property itself will take an array of routes, So we just have a classic tree structure here.
databases
children
data
data management
We can define a dynamic URL parameter by putting a colon in front of whatever that parameter is. This case, we're going to be looking up animals by their name in our database, so we'll set up colon name as that URL parameter. Doing this means that can navigate to routes that will look like animal /elephant, animal/aardvark, or any other dynamic property that we pass to the second half of that URL segment. You'll notice that we're dynamically generating a list of links that we're pulling from Firebase, so let me show you how I do that. In In the parent component, I have an array of documents that I pulled from Firestore so I can loop over them asynchronously with n g 4 and the async pipe. Then to build a link instead of passing it a string, I'll put brackets around the router link so we can pass it an expression, which in this case will be an array where each item in that array represents a URL segment.
So the first half of the segment is animals and the second half will be the animal's name. Because this is a parent component, we'll need to tell the router where to render the child components, which we can do with a router outlet. The The actual data in the database is just a collection of animals that have a few properties on each document. Inside the parent component, we can retrieve documents with pretty much just a single line of code, we inject Firestore in the constructor and then reference these documents as the animals property And call value changes to listen to them as a real time observable.
databases
data
data management
animals
livestock
documentation
In the child component, things are a little more tricky because we need to also listen to the change in the URL parameter to get the proper animal from the database. The Angular router provides a service called activated route that allows us to listen to state changes in the router. And then we'll also import the switch map operator from RxJS. The important thing to understand here is that the component is only initialized once When the first route is navigated to, any child routes that are navigated to after that won't be called with NG on a net. So what we wanna do here is use activated route to listen to changes in that URL parameter which is the animal's name, which we can do by calling route param map which returns an observable of the route parameters. Then when a change occurs, we'll call switch map to switch to an observable of the actual animal data from buyer store. Notice how we're calling params get name which matches the dynamic URL segment that we set in the router config. So that returns the actual name of the animal which we can then pass on to Firestore to retrieve as a single document. The last step is just to unwrap this document in the child component.
So we can do that with n g if animal async, Then set that as a template variable of animal and we'll just show some of the properties here in the components such as the name, bio, and image. And you now have a structured router tree that will scale up to as many documents as you have saved in the database. Up until this point, we've only been using router links to navigate, But you can also navigate directly from inside of the components TypeScript. There are many cases where you just can't use a link click to navigate to a page and you wanna do it in a more dynamic way.
databases
data
Maybe you have some really ugly animals in your database and you want to prompt the user to say yes before navigating. In this case, we will import the router directly into our component. We'll set up a click handler here that will first prompt the user to confirm that they wanna navigate to this page. And then if they type in yes, we'll go ahead and navigate to that page manually with the router. You can say router dot navigate and have it go to the array of URL segments that you point it to. Back in the HTML, we can go ahead and remove the router link and replace it with the click event that will run our click handler whenever it's clicked. So the key takeaway here is that you can navigate anywhere in your Angular code outside of the scope of a regular hyperlink. Now I wanna go ahead and switch gears and show you a couple of things that are just super useful to do with the router. Let's say you want to create a catch all route that will serve more or less as a 404 page if the user routes to a component that doesn't exist. We can generate a new component to show the content and then we'll say path star star as a wildcard, and you wanna make sure that this route is the very last route in your tree. Then if we go and type in some random URL into the browser, it's going to pull up our error component instead of just throwing a regular error to the end user. Then another very common thing you might wanna do is instead of routing to a component, you might just want to redirect to a different route. So let's say we have a common misspelling for animals, We can just redirect to the main animal's route. When you set up a redirect route, you'll have to also add in the path match option. Otherwise, Angular will throw an error. If we go and navigate to this route on the browser, you'll see it redirects us to the animals component instead of bringing up the error component that we just created. Another cool thing you can do is use the router link active directive to provide a CSS class whenever a certain route is active. This makes it really easy to build out UI features that show the user which link they're currently on. It expects a list of CSS classes on the right hand side. So we'll define an active CSS class that will make the font bold and a different color.
Now you can see we get a clear UI change every time we go to a different link. For the next few minutes, I wanna move a little beyond the basics and talk about guards to protect routes, create reusable code and preload data into your components. A guard is just an Angular service that has some special interfaces that we can implement to do things with the router. One of the most common use cases is to protect routes from unauthorized users. Let's go ahead and run n g generate guard admin that will protect our routes from any non admin users. The special interface we'll be using here is can activate, which will only activate this route if the guard resolves to true. Let's go ahead and lock down our animals route by adding the can activate property with the admin guard. If we go into the guard itself, you'll see that is decorated with injectable just like any other Angular service. The only special thing is it has this can activate interface that gives us some information about the state of the route. In order for the guard to work, we just need to return a Boolean, which can be a primitive or it can be an observable or promise. If it's an observable, it's going to automatically subscribe for you.
security
law enforcement
So we'll go ahead and send an alert that says only admins allowed, and then we'll return false to block access to this route. If we try to navigate to the animals page, you can see we get this alert and the component is never rendered. But more often than not, you'll need to do this asynchronously by checking with some API if this user has authorization. We can simulate this by setting up a timer of 1,000 milliseconds, Then we'll need to map the emitted value down to a boolean. Then we can also use the tap operator to show an alert or this is a good place to navigate to a login page or something along those lines. If we try to navigate to the page at this time, you'll see we get a one second delay, and then it finally blocks the route after this observable is resolved. Can activate is a very powerful interface at your disposal, but there's also another one called resolve that can preload data into your route. Do you remember earlier how in the animal detail component, we listened to the name parameter and then switch map to a different observable?
Well, maybe there's a better way we can do Imagine we wanted to preload this data on multiple different components. We would have to write this code for each one of them. Instead of repeating ourselves, Let's generate a guard called preload. Instead of using the can activate interface, we'll use the resolve interface and you could strong type this as well, but for now, we'll just use any.
programming
Then Then we'll change the method name to resolve and it's pretty similar to can activate, but instead we'll return the actual data that we want to be available when this route is navigated to. And commonly, that's going to be an observable form because you're probably pulling this data from some external API. In our case, we'll do it with Angular Firestore so we can inject that in the instructor. Then the guard will have the actual parameter name available as a plain object, which we can retrieve with next dot parammap.getname. Then we can just return the data as an observable, but we have to pipe in the first operator because Firebase returns real time stream, and we need this observable to complete in order for it to work properly. Now we can just comment out all of our previous code, and instead, we'll just Define the animal as the data that is now available on this route when it's navigated to. It's now available on the route data property, and then we can apply it to this route going back to our router config, then add the resolve property to our preload guard. If we open up the app, it's going to work in exactly the same way as it did before. But now, we've isolated this code in a reusable way that we can apply to multiple routes as needed. Hopefully, that gives you a basic idea about how powerful the Angular router can be. I'm gonna go ahead and wrap things up there. If this video helped you, please like and subscribe. And if you really wanna master the basics of Angular, consider becoming a pro member at angularfirebase.com. You'll get access to a whole bunch of exclusive content designed to help you build and ship your app faster. Thanks for watching and I'll talk to you soon.
The router is one of the most powerful yet underutilized tools in Angular. In addition to defining the URL structure for your app, it can also be used to control performance with lazy loading and help you write dry code with resolvers and guards. Over the next few minutes you'll learn the basics of the Angular 6 router, plus few advanced techniques to preload data from Firebase and protect routes from unauthenticated users. If you're new here, like and subscribe and grab the full write up from angularfirebase com. The first thing we'll do to get started is generate a brand new Angular 6 app with the router flag. That'll just give us a routing module automatically. The first thing we'll wanna look at is the router outlet. When you route to a component, it needs to be the child of some other component, which by default will be the app component and the root of the project. So the outlet tells Angular where to render a component based on the URL that the user navigates to. We can define our routes by going into the app routing module, and you'll see we have an array that's typed to the route's interface. We can define each route in our application as an object, which will take a couple of configuration parameters. The most basic use case would be to give your route a path and then route it to a specific component that you've generated. Let's run n g generate component and we'll call this the home page. Now the home page we could set up as the root path. So we'll give that a path property of an empty string, then set the component option to the home component. If we serve the app, we should see the home component rendered at the position of that router outlet. Then notice how other content in the home component is still there such just the logo and the header. That'd be a good place to put a nav bar and a footer and things that'll be present on every page. That's a good start, but let's look at how we can navigate between multiple components by generating another one called animals. Then we can import the component into our router module and set up another path and component property for this route. When setting up hyperlinks in Angular, you don't use a normal h ref attribute like you would in a plain HTML page. If you use a regular h ref, it'll cause your Angular to completely reload whenever it's clicked. Instead we use the router link directive which tells Angular to treat this as an internal route, Then we simply pass it the path that we would normally route to with a link. So now if we open up the app in the browser, we can click on this animals link And it will route us to the corresponding component. So that takes care of your most basic use case, but what happens in the real world is generally you're pulling some information from a database, Then route to a specific ID to show more information about that item and you might have 1,000 or 1,000,000 of items in your database, so you can't just hard code all of those routes manually. In this next section, we'll create a component called animal detail and we're going to make it a child route of animals. You can create child routes That will be rendered inside of their parent by adding the children property to the parent route. The children property itself will take an array of routes, So we just have a classic tree structure here. We can define a dynamic URL parameter by putting a colon in front of whatever that parameter is. This case, we're going to be looking up animals by their name in our database, so we'll set up colon name as that URL parameter. Doing this means that can navigate to routes that will look like animal /elephant, animal/aardvark, or any other dynamic property that we pass to the second half of that URL segment. You'll notice that we're dynamically generating a list of links that we're pulling from Firebase, so let me show you how I do that. In In the parent component, I have an array of documents that I pulled from Firestore so I can loop over them asynchronously with n g 4 and the async pipe. Then to build a link instead of passing it a string, I'll put brackets around the router link so we can pass it an expression, which in this case will be an array where each item in that array represents a URL segment. So the first half of the segment is animals and the second half will be the animal's name. Because this is a parent component, we'll need to tell the router where to render the child components, which we can do with a router outlet. The The actual data in the database is just a collection of animals that have a few properties on each document. Inside the parent component, we can retrieve documents with pretty much just a single line of code, we inject Firestore in the constructor and then reference these documents as the animals property And call value changes to listen to them as a real time observable. In the child component, things are a little more tricky because we need to also listen to the change in the URL parameter to get the proper animal from the database. The Angular router provides a service called activated route that allows us to listen to state changes in the router. And then we'll also import the switch map operator from RxJS. The important thing to understand here is that the component is only initialized once When the first route is navigated to, any child routes that are navigated to after that won't be called with NG on a net. So what we wanna do here is use activated route to listen to changes in that URL parameter which is the animal's name, which we can do by calling route param map which returns an observable of the route parameters. Then when a change occurs, we'll call switch map to switch to an observable of the actual animal data from buyer store. Notice how we're calling params get name which matches the dynamic URL segment that we set in the router config. So that returns the actual name of the animal which we can then pass on to Firestore to retrieve as a single document. The last step is just to unwrap this document in the child component. So we can do that with n g if animal async, Then set that as a template variable of animal and we'll just show some of the properties here in the components such as the name, bio, and image. And you now have a structured router tree that will scale up to as many documents as you have saved in the database. Up until this point, we've only been using router links to navigate, But you can also navigate directly from inside of the components TypeScript. There are many cases where you just can't use a link click to navigate to a page and you wanna do it in a more dynamic way. Maybe you have some really ugly animals in your database and you want to prompt the user to say yes before navigating. In this case, we will import the router directly into our component. We'll set up a click handler here that will first prompt the user to confirm that they wanna navigate to this page. And then if they type in yes, we'll go ahead and navigate to that page manually with the router. You can say router dot navigate and have it go to the array of URL segments that you point it to. Back in the HTML, we can go ahead and remove the router link and replace it with the click event that will run our click handler whenever it's clicked. So the key takeaway here is that you can navigate anywhere in your Angular code outside of the scope of a regular hyperlink. Now I wanna go ahead and switch gears and show you a couple of things that are just super useful to do with the router. Let's say you want to create a catch all route that will serve more or less as a 404 page if the user routes to a component that doesn't exist. We can generate a new component to show the content and then we'll say path star star as a wildcard, and you wanna make sure that this route is the very last route in your tree. Then if we go and type in some random URL into the browser, it's going to pull up our error component instead of just throwing a regular error to the end user. Then another very common thing you might wanna do is instead of routing to a component, you might just want to redirect to a different route. So let's say we have a common misspelling for animals, We can just redirect to the main animal's route. When you set up a redirect route, you'll have to also add in the path match option. Otherwise, Angular will throw an error. If we go and navigate to this route on the browser, you'll see it redirects us to the animals component instead of bringing up the error component that we just created. Another cool thing you can do is use the router link active directive to provide a CSS class whenever a certain route is active. This makes it really easy to build out UI features that show the user which link they're currently on. It expects a list of CSS classes on the right hand side. So we'll define an active CSS class that will make the font bold and a different color. Now you can see we get a clear UI change every time we go to a different link. For the next few minutes, I wanna move a little beyond the basics and talk about guards to protect routes, create reusable code and preload data into your components. A guard is just an Angular service that has some special interfaces that we can implement to do things with the router. One of the most common use cases is to protect routes from unauthorized users. Let's go ahead and run n g generate guard admin that will protect our routes from any non admin users. The special interface we'll be using here is can activate, which will only activate this route if the guard resolves to true. Let's go ahead and lock down our animals route by adding the can activate property with the admin guard. If we go into the guard itself, you'll see that is decorated with injectable just like any other Angular service. The only special thing is it has this can activate interface that gives us some information about the state of the route. In order for the guard to work, we just need to return a Boolean, which can be a primitive or it can be an observable or promise. If it's an observable, it's going to automatically subscribe for you. So we'll go ahead and send an alert that says only admins allowed, and then we'll return false to block access to this route. If we try to navigate to the animals page, you can see we get this alert and the component is never rendered. But more often than not, you'll need to do this asynchronously by checking with some API if this user has authorization. We can simulate this by setting up a timer of 1,000 milliseconds, Then we'll need to map the emitted value down to a boolean. Then we can also use the tap operator to show an alert or this is a good place to navigate to a login page or something along those lines. If we try to navigate to the page at this time, you'll see we get a one second delay, and then it finally blocks the route after this observable is resolved. Can activate is a very powerful interface at your disposal, but there's also another one called resolve that can preload data into your route. Do you remember earlier how in the animal detail component, we listened to the name parameter and then switch map to a different observable? Well, maybe there's a better way we can do Imagine we wanted to preload this data on multiple different components. We would have to write this code for each one of them. Instead of repeating ourselves, Let's generate a guard called preload. Instead of using the can activate interface, we'll use the resolve interface and you could strong type this as well, but for now, we'll just use any. Then Then we'll change the method name to resolve and it's pretty similar to can activate, but instead we'll return the actual data that we want to be available when this route is navigated to. And commonly, that's going to be an observable form because you're probably pulling this data from some external API. In our case, we'll do it with Angular Firestore so we can inject that in the instructor. Then the guard will have the actual parameter name available as a plain object, which we can retrieve with next dot parammap.getname. Then we can just return the data as an observable, but we have to pipe in the first operator because Firebase returns real time stream, and we need this observable to complete in order for it to work properly. Now we can just comment out all of our previous code, and instead, we'll just Define the animal as the data that is now available on this route when it's navigated to. It's now available on the route data property, and then we can apply it to this route going back to our router config, then add the resolve property to our preload guard. If we open up the app, it's going to work in exactly the same way as it did before. But now, we've isolated this code in a reusable way that we can apply to multiple routes as needed. Hopefully, that gives you a basic idea about how powerful the Angular router can be. I'm gonna go ahead and wrap things up there. If this video helped you, please like and subscribe. And if you really wanna master the basics of Angular, consider becoming a pro member at angularfirebase.com. You'll get access to a whole bunch of exclusive content designed to help you build and ship your app faster. Thanks for watching and I'll talk to you soon.
The
the
router
router
is
is
one
one
of
of
the
the
most
most
powerful
powerful
yet
yet
underutilized
underutilized
tools
tools
in
in
Angular.
angular
In
in
addition
addition
to
to
defining
defining
the
the
URL
url
structure
structure
for
for
your
your
app,
app
it
it
can
can
also
also
be
be
used
used
to
to
control
control
performance
performance
with
with
lazy
lazy
loading
loading
and
and
help
help
you
you
write
write
dry
dry
code
code
with
with
resolvers
resolvers
and
and
guards.
guards
Over
over
the
the
next
next
few
few
minutes
minutes
you'll
you'll
learn
learn
the
the
basics
basics
of
of
the
the
Angular
angular
6
6
router,
router
plus
plus
few
few
advanced
advanced
techniques
techniques
to
to
preload
preload
data
data
from
from
Firebase
firebase
and
and
protect
protect
routes
routes
from
from
unauthenticated
unauthenticated
users.
users
If
if
you're
you're
new
new
here,
here
like
like
and
and
subscribe
subscribe
and
and
grab
grab
the
the
full
full
write
write
up
up
from
from
angularfirebase
angularfirebase
com.
com
The
the
first
first
thing
thing
we'll
we'll
do
do
to
to
get
get
started
started
is
is
generate
generate
a
a
brand
brand
new
new
Angular
angular
6
6
app
app
with
with
the
the
router
router
flag.
flag
That'll
that'll
just
just
give
give
us
us
a
a
routing
routing
module
module
automatically.
automatically
The
the
first
first
thing
thing
we'll
we'll
wanna
wanna
look
look
at
at
is
is
the
the
router
router
outlet.
outlet
When
when
you
you
route
route
to
to
a
a
component,
component
it
it
needs
needs
to
to
be
be
the
the
child
child
of
of
some
some
other
other
component,
component
which
which
by
by
default
default
will
will
be
be
the
the
app
app
component
component
and
and
the
the
root
root
of
of
the
the
project.
project
So
so
the
the
outlet
outlet
tells
tells
Angular
angular
where
where
to
to
render
render
a
a
component
component
based
based
on
on
the
the
URL
url
that
that
the
the
user
user
navigates
navigates
to.
to
We
we
can
can
define
define
our
our
routes
routes
by
by
going
going
into
into
the
the
app
app
routing
routing
module,
module
and
and
you'll
you'll
see
see
we
we
have
have
an
an
array
array
that's
that's
typed
typed
to
to
the
the
route's
route's
interface.
interface
We
we
can
can
define
define
each
each
route
route
in
in
our
our
application
application
as
as
an
an
object,
object
which
which
will
will
take
take
a
a
couple
couple
of
of
configuration
configuration
parameters.
parameters
The
the
most
most
basic
basic
use
use
case
case
would
would
be
be
to
to
give
give
your
your
route
route
a
a
path
path
and
and
then
then
route
route
it
it
to
to
a
a
specific
specific
component
component
that
that
you've
you've
generated.
generated
Let's
let's
run
run
n
n
g
g
generate
generate
component
component
and
and
we'll
we'll
call
call
this
this
the
the
home
home
page.
page
Now
now
the
the
home
home
page
page
we
we
could
could
set
set
up
up
as
as
the
the
root
root
path.
path
So
so
we'll
we'll
give
give
that
that
a
a
path
path
property
property
of
of
an
an
empty
empty
string,
string
then
then
set
set
the
the
component
component
option
option
to
to
the
the
home
home
component.
component
If
if
we
we
serve
serve
the
the
app,
app
we
we
should
should
see
see
the
the
home
home
component
component
rendered
rendered
at
at
the
the
position
position
of
of
that
that
router
router
outlet.
outlet
Then
then
notice
notice
how
how
other
other
content
content
in
in
the
the
home
home
component
component
is
is
still
still
there
there
such
such
just
just
the
the
logo
logo
and
and
the
the
header.
header
That'd
that'd
be
be
a
a
good
good
place
place
to
to
put
put
a
a
nav
nav
bar
bar
and
and
a
a
footer
footer
and
and
things
things
that'll
that'll
be
be
present
present
on
on
every
every
page.
page
That's
that's
a
a
good
good
start,
start
but
but
let's
let's
look
look
at
at
how
how
we
we
can
can
navigate
navigate
between
between
multiple
multiple
components
components
by
by
generating
generating
another
another
one
one
called
called
animals.
animals
Then
then
we
we
can
can
import
import
the
the
component
component
into
into
our
our
router
router
module
module
and
and
set
set
up
up
another
another
path
path
and
and
component
component
property
property
for
for
this
this
route.
route
When
when
setting
setting
up
up
hyperlinks
hyperlinks
in
in
Angular,
angular
you
you
don't
don't
use
use
a
a
normal
normal
h
h
ref
ref
attribute
attribute
like
like
you
you
would
would
in
in
a
a
plain
plain
HTML
html
page.
page
If
if
you
you
use
use
a
a
regular
regular
h
h
ref,
ref
it'll
it'll
cause
cause
your
your
Angular
angular
to
to
completely
completely
reload
reload
whenever
whenever
it's
it's
clicked.
clicked
Instead
instead
we
we
use
use
the
the
router
router
link
link
directive
directive
which
which
tells
tells
Angular
angular
to
to
treat
treat
this
this
as
as
an
an
internal
internal
route,
route
Then
then
we
we
simply
simply
pass
pass
it
it
the
the
path
path
that
that
we
we
would
would
normally
normally
route
route
to
to
with
with
a
a
link.
link
So
so
now
now
if
if
we
we
open
open
up
up
the
the
app
app
in
in
the
the
browser,
browser
we
we
can
can
click
click
on
on
this
this
animals
animals
link
link
And
and
it
it
will
will
route
route
us
us
to
to
the
the
corresponding
corresponding
component.
component
So
so
that
that
takes
takes
care
care
of
of
your
your
most
most
basic
basic
use
use
case,
case
but
but
what
what
happens
happens
in
in
the
the
real
real
world
world
is
is
generally
generally
you're
you're
pulling
pulling
some
some
information
information
from
from
a
a
database,
database
Then
then
route
route
to
to
a
a
specific
specific
ID
id
to
to
show
show
more
more
information
information
about
about
that
that
item
item
and
and
you
you
might
might
have
have
1,000
1,000
or
or
1,000,000
1,000,000
of
of
items
items
in
in
your
your
database,
database
so
so
you
you
can't
can't
just
just
hard
hard
code
code
all
all
of
of
those
those
routes
routes
manually.
manually
In
in
this
this
next
next
section,
section
we'll
we'll
create
create
a
a
component
component
called
called
animal
animal
detail
detail
and
and
we're
we're
going
going
to
to
make
make
it
it
a
a
child
child
route
route
of
of
animals.
animals
You
you
can
can
create
create
child
child
routes
routes
That
that
will
will
be
be
rendered
rendered
inside
inside
of
of
their
their
parent
parent
by
by
adding
adding
the
the
children
children
property
property
to
to
the
the
parent
parent
route.
route
The
the
children
children
property
property
itself
itself
will
will
take
take
an
an
array
array
of
of
routes,
routes
So
so
we
we
just
just
have
have
a
a
classic
classic
tree
tree
structure
structure
here.
here
We
we
can
can
define
define
a
a
dynamic
dynamic
URL
url
parameter
parameter
by
by
putting
putting
a
a
colon
colon
in
in
front
front
of
of
whatever
whatever
that
that
parameter
parameter
is.
is
This
this
case,
case
we're
we're
going
going
to
to
be
be
looking
looking
up
up
animals
animals
by
by
their
their
name
name
in
in
our
our
database,
database
so
so
we'll
we'll
set
set
up
up
colon
colon
name
name
as
as
that
that
URL
url
parameter.
parameter
Doing
doing
this
this
means
means
that
that
can
can
navigate
navigate
to
to
routes
routes
that
that
will
will
look
look
like
like
animal
animal
/elephant,
/elephant
animal/aardvark,
animal/aardvark
or
or
any
any
other
other
dynamic
dynamic
property
property
that
that
we
we
pass
pass
to
to
the
the
second
second
half
half
of
of
that
that
URL
url
segment.
segment
You'll
you'll
notice
notice
that
that
we're
we're
dynamically
dynamically
generating
generating
a
a
list
list
of
of
links
links
that
that
we're
we're
pulling
pulling
from
from
Firebase,
firebase
so
so
let
let
me
me
show
show
you
you
how
how
I
i
do
do
that.
that
In
in
In
in
the
the
parent
parent
component,
component
I
i
have
have
an
an
array
array
of
of
documents
documents
that
that
I
i
pulled
pulled
from
from
Firestore
firestore
so
so
I
i
can
can
loop
loop
over
over
them
them
asynchronously
asynchronously
with
with
n
n
g
g
4
4
and
and
the
the
async
async
pipe.
pipe
Then
then
to
to
build
build
a
a
link
link
instead
instead
of
of
passing
passing
it
it
a
a
string,
string
I'll
i'll
put
put
brackets
brackets
around
around
the
the
router
router
link
link
so
so
we
we
can
can
pass
pass
it
it
an
an
expression,
expression
which
which
in
in
this
this
case
case
will
will
be
be
an
an
array
array
where
where
each
each
item
item
in
in
that
that
array
array
represents
represents
a
a
URL
url
segment.
segment
So
so
the
the
first
first
half
half
of
of
the
the
segment
segment
is
is
animals
animals
and
and
the
the
second
second
half
half
will
will
be
be
the
the
animal's
animal's
name.
name
Because
because
this
this
is
is
a
a
parent
parent
component,
component
we'll
we'll
need
need
to
to
tell
tell
the
the
router
router
where
where
to
to
render
render
the
the
child
child
components,
components
which
which
we
we
can
can
do
do
with
with
a
a
router
router
outlet.
outlet
The
the
The
the
actual
actual
data
data
in
in
the
the
database
database
is
is
just
just
a
a
collection
collection
of
of
animals
animals
that
that
have
have
a
a
few
few
properties
properties
on
on
each
each
document.
document
Inside
inside
the
the
parent
parent
component,
component
we
we
can
can
retrieve
retrieve
documents
documents
with
with
pretty
pretty
much
much
just
just
a
a
single
single
line
line
of
of
code,
code
we
we
inject
inject
Firestore
firestore
in
in
the
the
constructor
constructor
and
and
then
then
reference
reference
these
these
documents
documents
as
as
the
the
animals
animals
property
property
And
and
call
call
value
value
changes
changes
to
to
listen
listen
to
to
them
them
as
as
a
a
real
real
time
time
observable.
observable
In
in
the
the
child
child
component,
component
things
things
are
are
a
a
little
little
more
more
tricky
tricky
because
because
we
we
need
need
to
to
also
also
listen
listen
to
to
the
the
change
change
in
in
the
the
URL
url
parameter
parameter
to
to
get
get
the
the
proper
proper
animal
animal
from
from
the
the
database.
database
The
the
Angular
angular
router
router
provides
provides
a
a
service
service
called
called
activated
activated
route
route
that
that
allows
allows
us
us
to
to
listen
listen
to
to
state
state
changes
changes
in
in
the
the
router.
router
And
and
then
then
we'll
we'll
also
also
import
import
the
the
switch
switch
map
map
operator
operator
from
from
RxJS.
rxjs
The
the
important
important
thing
thing
to
to
understand
understand
here
here
is
is
that
that
the
the
component
component
is
is
only
only
initialized
initialized
once
once
When
when
the
the
first
first
route
route
is
is
navigated
navigated
to,
to
any
any
child
child
routes
routes
that
that
are
are
navigated
navigated
to
to
after
after
that
that
won't
won't
be
be
called
called
with
with
NG
ng
on
on
a
a
net.
net
So
so
what
what
we
we
wanna
wanna
do
do
here
here
is
is
use
use
activated
activated
route
route
to
to
listen
listen
to
to
changes
changes
in
in
that
that
URL
url
parameter
parameter
which
which
is
is
the
the
animal's
animal's
name,
name
which
which
we
we
can
can
do
do
by
by
calling
calling
route
route
param
param
map
map
which
which
returns
returns
an
an
observable
observable
of
of
the
the
route
route
parameters.
parameters
Then
then
when
when
a
a
change
change
occurs,
occurs
we'll
we'll
call
call
switch
switch
map
map
to
to
switch
switch
to
to
an
an
observable
observable
of
of
the
the
actual
actual
animal
animal
data
data
from
from
buyer
buyer
store.
store
Notice
notice
how
how
we're
we're
calling
calling
params
params
get
get
name
name
which
which
matches
matches
the
the
dynamic
dynamic
URL
url
segment
segment
that
that
we
we
set
set
in
in
the
the
router
router
config.
config
So
so
that
that
returns
returns
the
the
actual
actual
name
name
of
of
the
the
animal
animal
which
which
we
we
can
can
then
then
pass
pass
on
on
to
to
Firestore
firestore
to
to
retrieve
retrieve
as
as
a
a
single
single
document.
document
The
the
last
last
step
step
is
is
just
just
to
to
unwrap
unwrap
this
this
document
document
in
in
the
the
child
child
component.
component
So
so
we
we
can
can
do
do
that
that
with
with
n
n
g
g
if
if
animal
animal
async,
async
Then
then
set
set
that
that
as
as
a
a
template
template
variable
variable
of
of
animal
animal
and
and
we'll
we'll
just
just
show
show
some
some
of
of
the
the
properties
properties
here
here
in
in
the
the
components
components
such
such
as
as
the
the
name,
name
bio,
bio
and
and
image.
image
And
and
you
you
now
now
have
have
a
a
structured
structured
router
router
tree
tree
that
that
will
will
scale
scale
up
up
to
to
as
as
many
many
documents
documents
as
as
you
you
have
have
saved
saved
in
in
the
the
database.
database
Up
up
until
until
this
this
point,
point
we've
we've
only
only
been
been
using
using
router
router
links
links
to
to
navigate,
navigate
But
but
you
you
can
can
also
also
navigate
navigate
directly
directly
from
from
inside
inside
of
of
the
the
components
components
TypeScript.
typescript
There
there
are
are
many
many
cases
cases
where
where
you
you
just
just
can't
can't
use
use
a
a
link
link
click
click
to
to
navigate
navigate
to
to
a
a
page
page
and
and
you
you
wanna
wanna
do
do
it
it
in
in
a
a
more
more
dynamic
dynamic
way.
way
Maybe
maybe
you
you
have
have
some
some
really
really
ugly
ugly
animals
animals
in
in
your
your
database
database
and
and
you
you
want
want
to
to
prompt
prompt
the
the
user
user
to
to
say
say
yes
yes
before
before
navigating.
navigating
In
in
this
this
case,
case
we
we
will
will
import
import
the
the
router
router
directly
directly
into
into
our
our
component.
component
We'll
we'll
set
set
up
up
a
a
click
click
handler
handler
here
here
that
that
will
will
first
first
prompt
prompt
the
the
user
user
to
to
confirm
confirm
that
that
they
they
wanna
wanna
navigate
navigate
to
to
this
this
page.
page
And
and
then
then
if
if
they
they
type
type
in
in
yes,
yes
we'll
we'll
go
go
ahead
ahead
and
and
navigate
navigate
to
to
that
that
page
page
manually
manually
with
with
the
the
router.
router
You
you
can
can
say
say
router
router
dot
dot
navigate
navigate
and
and
have
have
it
it
go
go
to
to
the
the
array
array
of
of
URL
url
segments
segments
that
that
you
you
point
point
it
it
to.
to
Back
back
in
in
the
the
HTML,
html
we
we
can
can
go
go
ahead
ahead
and
and
remove
remove
the
the
router
router
link
link
and
and
replace
replace
it
it
with
with
the
the
click
click
event
event
that
that
will
will
run
run
our
our
click
click
handler
handler
whenever
whenever
it's
it's
clicked.
clicked
So
so
the
the
key
key
takeaway
takeaway
here
here
is
is
that
that
you
you
can
can
navigate
navigate
anywhere
anywhere
in
in
your
your
Angular
angular
code
code
outside
outside
of
of
the
the
scope
scope
of
of
a
a
regular
regular
hyperlink.
hyperlink
Now
now
I
i
wanna
wanna
go
go
ahead
ahead
and
and
switch
switch
gears
gears
and
and
show
show
you
you
a
a
couple
couple
of
of
things
things
that
that
are
are
just
just
super
super
useful
useful
to
to
do
do
with
with
the
the
router.
router
Let's
let's
say
say
you
you
want
want
to
to
create
create
a
a
catch
catch
all
all
route
route
that
that
will
will
serve
serve
more
more
or
or
less
less
as
as
a
a
404
404
page
page
if
if
the
the
user
user
routes
routes
to
to
a
a
component
component
that
that
doesn't
doesn't
exist.
exist
We
we
can
can
generate
generate
a
a
new
new
component
component
to
to
show
show
the
the
content
content
and
and
then
then
we'll
we'll
say
say
path
path
star
star
star
star
as
as
a
a
wildcard,
wildcard
and
and
you
you
wanna
wanna
make
make
sure
sure
that
that
this
this
route
route
is
is
the
the
very
very
last
last
route
route
in
in
your
your
tree.
tree
Then
then
if
if
we
we
go
go
and
and
type
type
in
in
some
some
random
random
URL
url
into
into
the
the
browser,
browser
it's
it's
going
going
to
to
pull
pull
up
up
our
our
error
error
component
component
instead
instead
of
of
just
just
throwing
throwing
a
a
regular
regular
error
error
to
to
the
the
end
end
user.
user
Then
then
another
another
very
very
common
common
thing
thing
you
you
might
might
wanna
wanna
do
do
is
is
instead
instead
of
of
routing
routing
to
to
a
a
component,
component
you
you
might
might
just
just
want
want
to
to
redirect
redirect
to
to
a
a
different
different
route.
route
So
so
let's
let's
say
say
we
we
have
have
a
a
common
common
misspelling
misspelling
for
for
animals,
animals
We
we
can
can
just
just
redirect
redirect
to
to
the
the
main
main
animal's
animal's
route.
route
When
when
you
you
set
set
up
up
a
a
redirect
redirect
route,
route
you'll
you'll
have
have
to
to
also
also
add
add
in
in
the
the
path
path
match
match
option.
option
Otherwise,
otherwise
Angular
angular
will
will
throw
throw
an
an
error.
error
If
if
we
we
go
go
and
and
navigate
navigate
to
to
this
this
route
route
on
on
the
the
browser,
browser
you'll
you'll
see
see
it
it
redirects
redirects
us
us
to
to
the
the
animals
animals
component
component
instead
instead
of
of
bringing
bringing
up
up
the
the
error
error
component
component
that
that
we
we
just
just
created.
created
Another
another
cool
cool
thing
thing
you
you
can
can
do
do
is
is
use
use
the
the
router
router
link
link
active
active
directive
directive
to
to
provide
provide
a
a
CSS
css
class
class
whenever
whenever
a
a
certain
certain
route
route
is
is
active.
active
This
this
makes
makes
it
it
really
really
easy
easy
to
to
build
build
out
out
UI
ui
features
features
that
that
show
show
the
the
user
user
which
which
link
link
they're
they're
currently
currently
on.
on
It
it
expects
expects
a
a
list
list
of
of
CSS
css
classes
classes
on
on
the
the
right
right
hand
hand
side.
side
So
so
we'll
we'll
define
define
an
an
active
active
CSS
css
class
class
that
that
will
will
make
make
the
the
font
font
bold
bold
and
and
a
a
different
different
color.
color
Now
now
you
you
can
can
see
see
we
we
get
get
a
a
clear
clear
UI
ui
change
change
every
every
time
time
we
we
go
go
to
to
a
a
different
different
link.
link
For
for
the
the
next
next
few
few
minutes,
minutes
I
i
wanna
wanna
move
move
a
a
little
little
beyond
beyond
the
the
basics
basics
and
and
talk
talk
about
about
guards
guards
to
to
protect
protect
routes,
routes
create
create
reusable
reusable
code
code
and
and
preload
preload
data
data
into
into
your
your
components.
components
A
a
guard
guard
is
is
just
just
an
an
Angular
angular
service
service
that
that
has
has
some
some
special
special
interfaces
interfaces
that
that
we
we
can
can
implement
implement
to
to
do
do
things
things
with
with
the
the
router.
router
One
one
of
of
the
the
most
most
common
common
use
use
cases
cases
is
is
to
to
protect
protect
routes
routes
from
from
unauthorized
unauthorized
users.
users
Let's
let's
go
go
ahead
ahead
and
and
run
run
n
n
g
g
generate
generate
guard
guard
admin
admin
that
that
will
will
protect
protect
our
our
routes
routes
from
from
any
any
non
non
admin
admin
users.
users
The
the
special
special
interface
interface
we'll
we'll
be
be
using
using
here
here
is
is
can
can
activate,
activate
which
which
will
will
only
only
activate
activate
this
this
route
route
if
if
the
the
guard
guard
resolves
resolves
to
to
true.
true
Let's
let's
go
go
ahead
ahead
and
and
lock
lock
down
down
our
our
animals
animals
route
route
by
by
adding
adding
the
the
can
can
activate
activate
property
property
with
with
the
the
admin
admin
guard.
guard
If
if
we
we
go
go
into
into
the
the
guard
guard
itself,
itself
you'll
you'll
see
see
that
that
is
is
decorated
decorated
with
with
injectable
injectable
just
just
like
like
any
any
other
other
Angular
angular
service.
service
The
the
only
only
special
special
thing
thing
is
is
it
it
has
has
this
this
can
can
activate
activate
interface
interface
that
that
gives
gives
us
us
some
some
information
information
about
about
the
the
state
state
of
of
the
the
route.
route
In
in
order
order
for
for
the
the
guard
guard
to
to
work,
work
we
we
just
just
need
need
to
to
return
return
a
a
Boolean,
boolean
which
which
can
can
be
be
a
a
primitive
primitive
or
or
it
it
can
can
be
be
an
an
observable
observable
or
or
promise.
promise
If
if
it's
it's
an
an
observable,
observable
it's
it's
going
going
to
to
automatically
automatically
subscribe
subscribe
for
for
you.
you
So
so
we'll
we'll
go
go
ahead
ahead
and
and
send
send
an
an
alert
alert
that
that
says
says
only
only
admins
admins
allowed,
allowed
and
and
then
then
we'll
we'll
return
return
false
false
to
to
block
block
access
access
to
to
this
this
route.
route
If
if
we
we
try
try
to
to
navigate
navigate
to
to
the
the
animals
animals
page,
page
you
you
can
can
see
see
we
we
get
get
this
this
alert
alert
and
and
the
the
component
component
is
is
never
never
rendered.
rendered
But
but
more
more
often
often
than
than
not,
not
you'll
you'll
need
need
to
to
do
do
this
this
asynchronously
asynchronously
by
by
checking
checking
with
with
some
some
API
api
if
if
this
this
user
user
has
has
authorization.
authorization
We
we
can
can
simulate
simulate
this
this
by
by
setting
setting
up
up
a
a
timer
timer
of
of
1,000
1,000
milliseconds,
milliseconds
Then
then
we'll
we'll
need
need
to
to
map
map
the
the
emitted
emitted
value
value
down
down
to
to
a
a
boolean.
boolean
Then
then
we
we
can
can
also
also
use
use
the
the
tap
tap
operator
operator
to
to
show
show
an
an
alert
alert
or
or
this
this
is
is
a
a
good
good
place
place
to
to
navigate
navigate
to
to
a
a
login
login
page
page
or
or
something
something
along
along
those
those
lines.
lines
If
if
we
we
try
try
to
to
navigate
navigate
to
to
the
the
page
page
at
at
this
this
time,
time
you'll
you'll
see
see
we
we
get
get
a
a
one
one
second
second
delay,
delay
and
and
then
then
it
it
finally
finally
blocks
blocks
the
the
route
route
after
after
this
this
observable
observable
is
is
resolved.
resolved
Can
can
activate
activate
is
is
a
a
very
very
powerful
powerful
interface
interface
at
at
your
your
disposal,
disposal
but
but
there's
there's
also
also
another
another
one
one
called
called
resolve
resolve
that
that
can
can
preload
preload
data
data
into
into
your
your
route.
route
Do
do
you
you
remember
remember
earlier
earlier
how
how
in
in
the
the
animal
animal
detail
detail
component,
component
we
we
listened
listened
to
to
the
the
name
name
parameter
parameter
and
and
then
then
switch
switch
map
map
to
to
a
a
different
different
observable?
observable
Well,
well
maybe
maybe
there's
there's
a
a
better
better
way
way
we
we
can
can
do
do
Imagine
imagine
we
we
wanted
wanted
to
to
preload
preload
this
this
data
data
on
on
multiple
multiple
different
different
components.
components
We
we
would
would
have
have
to
to
write
write
this
this
code
code
for
for
each
each
one
one
of
of
them.
them
Instead
instead
of
of
repeating
repeating
ourselves,
ourselves
Let's
let's
generate
generate
a
a
guard
guard
called
called
preload.
preload
Instead
instead
of
of
using
using
the
the
can
can
activate
activate
interface,
interface
we'll
we'll
use
use
the
the
resolve
resolve
interface
interface
and
and
you
you
could
could
strong
strong
type
type
this
this
as
as
well,
well
but
but
for
for
now,
now
we'll
we'll
just
just
use
use
any.
any
Then
then
Then
then
we'll
we'll
change
change
the
the
method
method
name
name
to
to
resolve
resolve
and
and
it's
it's
pretty
pretty
similar
similar
to
to
can
can
activate,
activate
but
but
instead
instead
we'll
we'll
return
return
the
the
actual
actual
data
data
that
that
we
we
want
want
to
to
be
be
available
available
when
when
this
this
route
route
is
is
navigated
navigated
to.
to
And
and
commonly,
commonly
that's
that's
going
going
to
to
be
be
an
an
observable
observable
form
form
because
because
you're
you're
probably
probably
pulling
pulling
this
this
data
data
from
from
some
some
external
external
API.
api
In
in
our
our
case,
case
we'll
we'll
do
do
it
it
with
with
Angular
angular
Firestore
firestore
so
so
we
we
can
can
inject
inject
that
that
in
in
the
the
instructor.
instructor
Then
then
the
the
guard
guard
will
will
have
have
the
the
actual
actual
parameter
parameter
name
name
available
available
as
as
a
a
plain
plain
object,
object
which
which
we
we
can
can
retrieve
retrieve
with
with
next
next
dot
dot
parammap.getname.
parammap.getname
Then
then
we
we
can
can
just
just
return
return
the
the
data
data
as
as
an
an
observable,
observable
but
but
we
we
have
have
to
to
pipe
pipe
in
in
the
the
first
first
operator
operator
because
because
Firebase
firebase
returns
returns
real
real
time
time
stream,
stream
and
and
we
we
need
need
this
this
observable
observable
to
to
complete
complete
in
in
order
order
for
for
it
it
to
to
work
work
properly.
properly
Now
now
we
we
can
can
just
just
comment
comment
out
out
all
all
of
of
our
our
previous
previous
code,
code
and
and
instead,
instead
we'll
we'll
just
just
Define
define
the
the
animal
animal
as
as
the
the
data
data
that
that
is
is
now
now
available
available
on
on
this
this
route
route
when
when
it's
it's
navigated
navigated
to.
to
It's
it's
now
now
available
available
on
on
the
the
route
route
data
data
property,
property
and
and
then
then
we
we
can
can
apply
apply
it
it
to
to
this
this
route
route
going
going
back
back
to
to
our
our
router
router
config,
config
then
then
add
add
the
the
resolve
resolve
property
property
to
to
our
our
preload
preload
guard.
guard
If
if
we
we
open
open
up
up
the
the
app,
app
it's
it's
going
going
to
to
work
work
in
in
exactly
exactly
the
the
same
same
way
way
as
as
it
it
did
did
before.
before
But
but
now,
now
we've
we've
isolated
isolated
this
this
code
code
in
in
a
a
reusable
reusable
way
way
that
that
we
we
can
can
apply
apply
to
to
multiple
multiple
routes
routes
as
as
needed.
needed
Hopefully,
hopefully
that
that
gives
gives
you
you
a
a
basic
basic
idea
idea
about
about
how
how
powerful
powerful
the
the
Angular
angular
router
router
can
can
be.
be
I'm
i'm
gonna
gonna
go
go
ahead
ahead
and
and
wrap
wrap
things
things
up
up
there.
there
If
if
this
this
video
video
helped
helped
you,
you
please
please
like
like
and
and
subscribe.
subscribe
And
and
if
if
you
you
really
really
wanna
wanna
master
master
the
the
basics
basics
of
of
Angular,
angular
consider
consider
becoming
becoming
a
a
pro
pro
member
member
at
at
angularfirebase.com.
angularfirebase.com
You'll
you'll
get
get
access
access
to
to
a
a
whole
whole
bunch
bunch
of
of
exclusive
exclusive
content
content
designed
designed
to
to
help
help
you
you
build
build
and
and
ship
ship
your
your
app
app
faster.
faster
Thanks
thanks
for
for
watching
watching
and
and
I'll
i'll
talk
talk
to
to
you
you
soon.
soon
success
The speaker explains the benefits of the Angular 6 router, including its powerful routing and advanced techniques for writing dry code. They provide a tutorial on creating a new Angular 6 app with the router flag, routes, hyperlinks, and creating a new component for animals. The speaker also explains how to navigate the dynamic URL parameters, access changes in the URL parameter, and use the activated route to listen to changes in the parameter. They also explain how to use the guard and preload data into component, activate the guard, and set up a special interface for the guard. Finally, they explain how to navigate the Angular code to protect routes and create reusable code for multiple routes, preload data into component, and use the preload guard function to handle multiple routes.
Angular Router - The Basics and Beyond
The router is one of the most powerful yet underutilized tools in Angular. In addition to defining the URL structure for your app, it can also be used to control performance with lazy loading and help you write dry code with resolvers and guards. Over the next few minutes you'll learn the basics of the Angular 6 router, plus few advanced techniques to preload data from Firebase and protect routes from unauthenticated users. If you're new here, like and subscribe and grab the full write up from angularfirebase com. The first thing we'll do to get started is generate a brand new Angular 6 app with the router flag. That'll just give us a routing module automatically. The first thing we'll wanna look at is the router outlet. When you route to a component, it needs to be the child of some other component, which by default will be the app component and the root of the project. So the outlet tells Angular where to render a component based on the URL that the user navigates to. We can define our routes by going into the app routing module, and you'll see we have an array that's typed to the route's interface. We can define each route in our application as an object, which will take a couple of configuration parameters. The most basic use case would be to give your route a path and then route it to a specific component that you've generated. Let's run n g generate component and we'll call this the home page. Now the home page we could set up as the root path. So we'll give that a path property of an empty string, then set the component option to the home component. If we serve the app, we should see the home component rendered at the position of that router outlet. Then notice how other content in the home component is still there such just the logo and the header. That'd be a good place to put a nav bar and a footer and things that'll be present on every page. That's a good start, but let's look at how we can navigate between multiple components by generating another one called animals. Then we can import the component into our router module and set up another path and component property for this route. When setting up hyperlinks in Angular, you don't use a normal h ref attribute like you would in a plain HTML page. If you use a regular h ref, it'll cause your Angular to completely reload whenever it's clicked. Instead we use the router link directive which tells Angular to treat this as an internal route, Then we simply pass it the path that we would normally route to with a link. So now if we open up the app in the browser, we can click on this animals link And it will route us to the corresponding component. So that takes care of your most basic use case, but what happens in the real world is generally you're pulling some information from a database, Then route to a specific ID to show more information about that item and you might have 1,000 or 1,000,000 of items in your database, so you can't just hard code all of those routes manually. In this next section, we'll create a component called animal detail and we're going to make it a child route of animals. You can create child routes That will be rendered inside of their parent by adding the children property to the parent route. The children property itself will take an array of routes, So we just have a classic tree structure here. We can define a dynamic URL parameter by putting a colon in front of whatever that parameter is. This case, we're going to be looking up animals by their name in our database, so we'll set up colon name as that URL parameter. Doing this means that can navigate to routes that will look like animal /elephant, animal/aardvark, or any other dynamic property that we pass to the second half of that URL segment. You'll notice that we're dynamically generating a list of links that we're pulling from Firebase, so let me show you how I do that. In In the parent component, I have an array of documents that I pulled from Firestore so I can loop over them asynchronously with n g 4 and the async pipe. Then to build a link instead of passing it a string, I'll put brackets around the router link so we can pass it an expression, which in this case will be an array where each item in that array represents a URL segment. So the first half of the segment is animals and the second half will be the animal's name. Because this is a parent component, we'll need to tell the router where to render the child components, which we can do with a router outlet. The The actual data in the database is just a collection of animals that have a few properties on each document. Inside the parent component, we can retrieve documents with pretty much just a single line of code, we inject Firestore in the constructor and then reference these documents as the animals property And call value changes to listen to them as a real time observable. In the child component, things are a little more tricky because we need to also listen to the change in the URL parameter to get the proper animal from the database. The Angular router provides a service called activated route that allows us to listen to state changes in the router. And then we'll also import the switch map operator from RxJS. The important thing to understand here is that the component is only initialized once When the first route is navigated to, any child routes that are navigated to after that won't be called with NG on a net. So what we wanna do here is use activated route to listen to changes in that URL parameter which is the animal's name, which we can do by calling route param map which returns an observable of the route parameters. Then when a change occurs, we'll call switch map to switch to an observable of the actual animal data from buyer store. Notice how we're calling params get name which matches the dynamic URL segment that we set in the router config. So that returns the actual name of the animal which we can then pass on to Firestore to retrieve as a single document. The last step is just to unwrap this document in the child component. So we can do that with n g if animal async, Then set that as a template variable of animal and we'll just show some of the properties here in the components such as the name, bio, and image. And you now have a structured router tree that will scale up to as many documents as you have saved in the database. Up until this point, we've only been using router links to navigate, But you can also navigate directly from inside of the components TypeScript. There are many cases where you just can't use a link click to navigate to a page and you wanna do it in a more dynamic way. Maybe you have some really ugly animals in your database and you want to prompt the user to say yes before navigating. In this case, we will import the router directly into our component. We'll set up a click handler here that will first prompt the user to confirm that they wanna navigate to this page. And then if they type in yes, we'll go ahead and navigate to that page manually with the router. You can say router dot navigate and have it go to the array of URL segments that you point it to. Back in the HTML, we can go ahead and remove the router link and replace it with the click event that will run our click handler whenever it's clicked. So the key takeaway here is that you can navigate anywhere in your Angular code outside of the scope of a regular hyperlink. Now I wanna go ahead and switch gears and show you a couple of things that are just super useful to do with the router. Let's say you want to create a catch all route that will serve more or less as a 404 page if the user routes to a component that doesn't exist. We can generate a new component to show the content and then we'll say path star star as a wildcard, and you wanna make sure that this route is the very last route in your tree. Then if we go and type in some random URL into the browser, it's going to pull up our error component instead of just throwing a regular error to the end user. Then another very common thing you might wanna do is instead of routing to a component, you might just want to redirect to a different route. So let's say we have a common misspelling for animals, We can just redirect to the main animal's route. When you set up a redirect route, you'll have to also add in the path match option. Otherwise, Angular will throw an error. If we go and navigate to this route on the browser, you'll see it redirects us to the animals component instead of bringing up the error component that we just created. Another cool thing you can do is use the router link active directive to provide a CSS class whenever a certain route is active. This makes it really easy to build out UI features that show the user which link they're currently on. It expects a list of CSS classes on the right hand side. So we'll define an active CSS class that will make the font bold and a different color. Now you can see we get a clear UI change every time we go to a different link. For the next few minutes, I wanna move a little beyond the basics and talk about guards to protect routes, create reusable code and preload data into your components. A guard is just an Angular service that has some special interfaces that we can implement to do things with the router. One of the most common use cases is to protect routes from unauthorized users. Let's go ahead and run n g generate guard admin that will protect our routes from any non admin users. The special interface we'll be using here is can activate, which will only activate this route if the guard resolves to true. Let's go ahead and lock down our animals route by adding the can activate property with the admin guard. If we go into the guard itself, you'll see that is decorated with injectable just like any other Angular service. The only special thing is it has this can activate interface that gives us some information about the state of the route. In order for the guard to work, we just need to return a Boolean, which can be a primitive or it can be an observable or promise. If it's an observable, it's going to automatically subscribe for you. So we'll go ahead and send an alert that says only admins allowed, and then we'll return false to block access to this route. If we try to navigate to the animals page, you can see we get this alert and the component is never rendered. But more often than not, you'll need to do this asynchronously by checking with some API if this user has authorization. We can simulate this by setting up a timer of 1,000 milliseconds, Then we'll need to map the emitted value down to a boolean. Then we can also use the tap operator to show an alert or this is a good place to navigate to a login page or something along those lines. If we try to navigate to the page at this time, you'll see we get a one second delay, and then it finally blocks the route after this observable is resolved. Can activate is a very powerful interface at your disposal, but there's also another one called resolve that can preload data into your route. Do you remember earlier how in the animal detail component, we listened to the name parameter and then switch map to a different observable? Well, maybe there's a better way we can do Imagine we wanted to preload this data on multiple different components. We would have to write this code for each one of them. Instead of repeating ourselves, Let's generate a guard called preload. Instead of using the can activate interface, we'll use the resolve interface and you could strong type this as well, but for now, we'll just use any. Then Then we'll change the method name to resolve and it's pretty similar to can activate, but instead we'll return the actual data that we want to be available when this route is navigated to. And commonly, that's going to be an observable form because you're probably pulling this data from some external API. In our case, we'll do it with Angular Firestore so we can inject that in the instructor. Then the guard will have the actual parameter name available as a plain object, which we can retrieve with next dot parammap.getname. Then we can just return the data as an observable, but we have to pipe in the first operator because Firebase returns real time stream, and we need this observable to complete in order for it to work properly. Now we can just comment out all of our previous code, and instead, we'll just Define the animal as the data that is now available on this route when it's navigated to. It's now available on the route data property, and then we can apply it to this route going back to our router config, then add the resolve property to our preload guard. If we open up the app, it's going to work in exactly the same way as it did before. But now, we've isolated this code in a reusable way that we can apply to multiple routes as needed. Hopefully, that gives you a basic idea about how powerful the Angular router can be. I'm gonna go ahead and wrap things up there. If this video helped you, please like and subscribe. And if you really wanna master the basics of Angular, consider becoming a pro member at angularfirebase.com. You'll get access to a whole bunch of exclusive content designed to help you build and ship your app faster. Thanks for watching and I'll talk to you soon.
The speaker explains the benefits of the Angular 6 router, including its powerful routing and advanced techniques for writing dry code. They provide a tutorial on creating a new Angular 6 app with the router flag, routes, hyperlinks, and creating a new component for animals. The speaker also explains how to navigate the dynamic URL parameters, access changes in the URL parameter, and use the activated route to listen to changes in the parameter. They also explain how to use the guard and preload data into component, activate the guard, and set up a special interface for the guard. Finally, they explain how to navigate the Angular code to protect routes and create reusable code for multiple routes, preload data into component, and use the preload guard function to handle multiple routes.

        [INST]
        You are youtuber called Fireship you make engaging high-intensity and entertaining coding tutorials and tech news. 
        you covers a wide range of topics relevant to programmers, aiming to help them learn and improve their skills quickly.
        
        Given the title of the video : Angular Router - The Basics and Beyond 
        and a small summary : The speaker explains the benefits of the Angular 6 router, including its powerful routing and advanced techniques for writing dry code. They provide a tutorial on creating a new Angular 6 app with the router flag, routes, hyperlinks, and creating a new component for animals. The speaker also explains how to navigate the dynamic URL parameters, access changes in the URL parameter, and use the activated route to listen to changes in the parameter. They also explain how to use the guard and preload data into component, activate the guard, and set up a special interface for the guard. Finally, they explain how to navigate the Angular code to protect routes and create reusable code for multiple routes, preload data into component, and use the preload guard function to handle multiple routes.
        [/INST]
        
        Generate the video : The router is one of the most powerful yet underutilized tools in Angular. In addition to defining the URL structure for your app, it can also be used to control performance with lazy loading and help you write dry code with resolvers and guards. Over the next few minutes you'll learn the basics of the Angular 6 router, plus few advanced techniques to preload data from Firebase and protect routes from unauthenticated users. If you're new here, like and subscribe and grab the full write up from angularfirebase com. The first thing we'll do to get started is generate a brand new Angular 6 app with the router flag. That'll just give us a routing module automatically. The first thing we'll wanna look at is the router outlet. When you route to a component, it needs to be the child of some other component, which by default will be the app component and the root of the project. So the outlet tells Angular where to render a component based on the URL that the user navigates to. We can define our routes by going into the app routing module, and you'll see we have an array that's typed to the route's interface. We can define each route in our application as an object, which will take a couple of configuration parameters. The most basic use case would be to give your route a path and then route it to a specific component that you've generated. Let's run n g generate component and we'll call this the home page. Now the home page we could set up as the root path. So we'll give that a path property of an empty string, then set the component option to the home component. If we serve the app, we should see the home component rendered at the position of that router outlet. Then notice how other content in the home component is still there such just the logo and the header. That'd be a good place to put a nav bar and a footer and things that'll be present on every page. That's a good start, but let's look at how we can navigate between multiple components by generating another one called animals. Then we can import the component into our router module and set up another path and component property for this route. When setting up hyperlinks in Angular, you don't use a normal h ref attribute like you would in a plain HTML page. If you use a regular h ref, it'll cause your Angular to completely reload whenever it's clicked. Instead we use the router link directive which tells Angular to treat this as an internal route, Then we simply pass it the path that we would normally route to with a link. So now if we open up the app in the browser, we can click on this animals link And it will route us to the corresponding component. So that takes care of your most basic use case, but what happens in the real world is generally you're pulling some information from a database, Then route to a specific ID to show more information about that item and you might have 1,000 or 1,000,000 of items in your database, so you can't just hard code all of those routes manually. In this next section, we'll create a component called animal detail and we're going to make it a child route of animals. You can create child routes That will be rendered inside of their parent by adding the children property to the parent route. The children property itself will take an array of routes, So we just have a classic tree structure here. We can define a dynamic URL parameter by putting a colon in front of whatever that parameter is. This case, we're going to be looking up animals by their name in our database, so we'll set up colon name as that URL parameter. Doing this means that can navigate to routes that will look like animal /elephant, animal/aardvark, or any other dynamic property that we pass to the second half of that URL segment. You'll notice that we're dynamically generating a list of links that we're pulling from Firebase, so let me show you how I do that. In In the parent component, I have an array of documents that I pulled from Firestore so I can loop over them asynchronously with n g 4 and the async pipe. Then to build a link instead of passing it a string, I'll put brackets around the router link so we can pass it an expression, which in this case will be an array where each item in that array represents a URL segment. So the first half of the segment is animals and the second half will be the animal's name. Because this is a parent component, we'll need to tell the router where to render the child components, which we can do with a router outlet. The The actual data in the database is just a collection of animals that have a few properties on each document. Inside the parent component, we can retrieve documents with pretty much just a single line of code, we inject Firestore in the constructor and then reference these documents as the animals property And call value changes to listen to them as a real time observable. In the child component, things are a little more tricky because we need to also listen to the change in the URL parameter to get the proper animal from the database. The Angular router provides a service called activated route that allows us to listen to state changes in the router. And then we'll also import the switch map operator from RxJS. The important thing to understand here is that the component is only initialized once When the first route is navigated to, any child routes that are navigated to after that won't be called with NG on a net. So what we wanna do here is use activated route to listen to changes in that URL parameter which is the animal's name, which we can do by calling route param map which returns an observable of the route parameters. Then when a change occurs, we'll call switch map to switch to an observable of the actual animal data from buyer store. Notice how we're calling params get name which matches the dynamic URL segment that we set in the router config. So that returns the actual name of the animal which we can then pass on to Firestore to retrieve as a single document. The last step is just to unwrap this document in the child component. So we can do that with n g if animal async, Then set that as a template variable of animal and we'll just show some of the properties here in the components such as the name, bio, and image. And you now have a structured router tree that will scale up to as many documents as you have saved in the database. Up until this point, we've only been using router links to navigate, But you can also navigate directly from inside of the components TypeScript. There are many cases where you just can't use a link click to navigate to a page and you wanna do it in a more dynamic way. Maybe you have some really ugly animals in your database and you want to prompt the user to say yes before navigating. In this case, we will import the router directly into our component. We'll set up a click handler here that will first prompt the user to confirm that they wanna navigate to this page. And then if they type in yes, we'll go ahead and navigate to that page manually with the router. You can say router dot navigate and have it go to the array of URL segments that you point it to. Back in the HTML, we can go ahead and remove the router link and replace it with the click event that will run our click handler whenever it's clicked. So the key takeaway here is that you can navigate anywhere in your Angular code outside of the scope of a regular hyperlink. Now I wanna go ahead and switch gears and show you a couple of things that are just super useful to do with the router. Let's say you want to create a catch all route that will serve more or less as a 404 page if the user routes to a component that doesn't exist. We can generate a new component to show the content and then we'll say path star star as a wildcard, and you wanna make sure that this route is the very last route in your tree. Then if we go and type in some random URL into the browser, it's going to pull up our error component instead of just throwing a regular error to the end user. Then another very common thing you might wanna do is instead of routing to a component, you might just want to redirect to a different route. So let's say we have a common misspelling for animals, We can just redirect to the main animal's route. When you set up a redirect route, you'll have to also add in the path match option. Otherwise, Angular will throw an error. If we go and navigate to this route on the browser, you'll see it redirects us to the animals component instead of bringing up the error component that we just created. Another cool thing you can do is use the router link active directive to provide a CSS class whenever a certain route is active. This makes it really easy to build out UI features that show the user which link they're currently on. It expects a list of CSS classes on the right hand side. So we'll define an active CSS class that will make the font bold and a different color. Now you can see we get a clear UI change every time we go to a different link. For the next few minutes, I wanna move a little beyond the basics and talk about guards to protect routes, create reusable code and preload data into your components. A guard is just an Angular service that has some special interfaces that we can implement to do things with the router. One of the most common use cases is to protect routes from unauthorized users. Let's go ahead and run n g generate guard admin that will protect our routes from any non admin users. The special interface we'll be using here is can activate, which will only activate this route if the guard resolves to true. Let's go ahead and lock down our animals route by adding the can activate property with the admin guard. If we go into the guard itself, you'll see that is decorated with injectable just like any other Angular service. The only special thing is it has this can activate interface that gives us some information about the state of the route. In order for the guard to work, we just need to return a Boolean, which can be a primitive or it can be an observable or promise. If it's an observable, it's going to automatically subscribe for you. So we'll go ahead and send an alert that says only admins allowed, and then we'll return false to block access to this route. If we try to navigate to the animals page, you can see we get this alert and the component is never rendered. But more often than not, you'll need to do this asynchronously by checking with some API if this user has authorization. We can simulate this by setting up a timer of 1,000 milliseconds, Then we'll need to map the emitted value down to a boolean. Then we can also use the tap operator to show an alert or this is a good place to navigate to a login page or something along those lines. If we try to navigate to the page at this time, you'll see we get a one second delay, and then it finally blocks the route after this observable is resolved. Can activate is a very powerful interface at your disposal, but there's also another one called resolve that can preload data into your route. Do you remember earlier how in the animal detail component, we listened to the name parameter and then switch map to a different observable? Well, maybe there's a better way we can do Imagine we wanted to preload this data on multiple different components. We would have to write this code for each one of them. Instead of repeating ourselves, Let's generate a guard called preload. Instead of using the can activate interface, we'll use the resolve interface and you could strong type this as well, but for now, we'll just use any. Then Then we'll change the method name to resolve and it's pretty similar to can activate, but instead we'll return the actual data that we want to be available when this route is navigated to. And commonly, that's going to be an observable form because you're probably pulling this data from some external API. In our case, we'll do it with Angular Firestore so we can inject that in the instructor. Then the guard will have the actual parameter name available as a plain object, which we can retrieve with next dot parammap.getname. Then we can just return the data as an observable, but we have to pipe in the first operator because Firebase returns real time stream, and we need this observable to complete in order for it to work properly. Now we can just comment out all of our previous code, and instead, we'll just Define the animal as the data that is now available on this route when it's navigated to. It's now available on the route data property, and then we can apply it to this route going back to our router config, then add the resolve property to our preload guard. If we open up the app, it's going to work in exactly the same way as it did before. But now, we've isolated this code in a reusable way that we can apply to multiple routes as needed. Hopefully, that gives you a basic idea about how powerful the Angular router can be. I'm gonna go ahead and wrap things up there. If this video helped you, please like and subscribe. And if you really wanna master the basics of Angular, consider becoming a pro member at angularfirebase.com. You'll get access to a whole bunch of exclusive content designed to help you build and ship your app faster. Thanks for watching and I'll talk to you soon.
        