How Angular Router Works?
Angular Router performs the following steps in order -
1. The router reads the browser URL the user wants to navigate to
2. The router applies a URL redirect (if one is defined otherwise page not found the error)
3. It figures out which router state corresponds to the URL
4. It runs the guards that are defined in the router state
5. It resolves the required data for the router state
6. It activates the Angular components to display the page
7. It manages navigations and repeats the steps above when a new page is requested.
Angular Router introduces the following terms and concepts -
1. <base href>
2. Router imports
3. Configuration
4. Router outlet
5. Router links
6. Router state
7. Activated route
8. Router events
What Is <base href>?
Most of all Angular routing apps must have the <base> element to the index.html or layout page in the <head> tag.
When using the PathLocationStrategy, need to tell the browsers what will be prefixed to the requested path to generate the URL.
You can specify a base URL like this –
<base href="/">
OR
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My Demo Apps</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
So if you had an Angular route defined like this –
{ path: 'users', component: UserComponent, data:{ title:'User List'} }
If <base href="/" >, the route become “/users”.
If <base href="/angular" >, the route become “/angular/users”.
How to Append Base URL to HTTP requests?
We can append base URL to HTTP requests using –
1. Dependency Injection
2. Using HttpInterceptors
The following example for append base URL using DI -
Firstly, we register a base URL provider in the NgModule and after register this BASE_URL, it is available universally in your Apps.
//Runtime or injector configuration
//providers is used for runtime injector configuration.
providers: [{ provide: 'BASE_URL', useFactory: getBaseUrl }],
Now provide factory method which gets the base URL from <base> element.
export function getBaseUrl() {
return document.getElementsByTagName('base')[0].href;
}
Finally, we can get the base URL injected and add it to URL-
export class GetUserComponent {
constructor(http: Http, @Inject('BASE_URL') baseUrl: string) {
http.get(baseUrl + 'api/users').subscribe(data => {
this.users = data.json();
}, error => console.error(error));
}
}
The following example for append base URL using HttpInterceptors –
If we wants to create an interceptor, we must create an Injectable class which implements HttpInterceptor.
Firstly, register interceptor in the module provider -
//Runtime or injector configuration
//providers is used for runtime injector configuration.
providers: [{ provide: HTTP_INTERCEPTORS, useClass: ApiInterceptor, multi: true } ],
And after register interceptor, to create –
@Injectable()
export class ApiInterceptor implements HttpInterceptor {
//Intercepts HttpRequest and handles them.
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const baseUrl = document.getElementsByTagName('base')[0].href;
const apiReq = req.clone({ url: `${baseUrl}${req.url}` });
return next.handle(apiReq);
}
}
Now we can access the base URL in your across apps.
What Is PathLocationStrategy?
A LocationStrategy used to configure the Location service that represents its state in the path of the browser's URL and the PathLocationStrategy is a default routing strategy.
When you are using the PathLocationStrategy, we must provide APP_BASE_HREF in the module or base element in the app document.
What Is HashLocationStrategy?
To enable HashLocationStrategy in an Angular app you pass {useHash: true} when you providing routes with router module and it like this.
//Composability and Grouping
//imports used for composing modules together.
imports: [
BrowserModule,
//enableTracing enables debugging purposes only
//useHash enables the location strategy that uses the URL fragment instead of the history API.
RouterModule.forRoot(appRoots, { enableTracing: true, useHash:true })
],
The HashLocationStrategy add the route path to the hash (#) in the browser’s URL.
The hash (#) part of the URL is called the hash fragment.
When using HashLocationStrategy for routing and providing a base Href, it always placed after the hash (#) e.g.
http://localhost:8080/#/UserDetail/1
The Hash style routing using the anchor tags technique to achieve client side routing and URL never sent to the server.
The anchor tag, when used along with the hash (#) allows us to jump to a place, within apps.
The URL would look like this -
1. http://localhost:8080
2. http://localhost:8080/#/Users
3. http://localhost:8080/#/UserDetail/1
In the above URLs “#/Users” and “#/UserDetail/1” never sent to the server.
How do you change the base URL dynamically?
Instead of setting the base element's href value, you can set the base URL programmatically, by providing for APP_BASE_HREF with your custom operation.
For more detail, referee to the above questions.
What Is Router imports?
It is an optional service that presents a special component view for a given URL. It has own library package- @angular/router and It is not a part of an Angular core.
The Angular package looks like this.
import {Routes, RouterModule,} from '@angular/router';
How to configure Angular routes?
A router has no routes until you configure it. So you are configuring the Angular router for accessing your apps URLs.
//Composability and Grouping
//imports used for composing NgModules together.
imports: [
BrowserModule,
//enableTracing is used for debugging purposes only
//Enables the location strategy that uses the URL fragment instead of the history API.
RouterModule.forRoot(appRoots, { enableTracing: true, useHash:false })
]
For the detail, you can refer Angular Routes example for the same.
What Is Router outlet?
The Router-Link, RouterLink-Active and the Router outlet is directive provided by the Angular RouterModule package. It’s provides the navigation and URLs manipulation capabilities. It also renders the components for specific location of your applications.
Both the template and templateUrl render the components where you use this directive.
<router-outlet> </router-outlet>
Is it possible to have a multiple router-outlet in the same template?
Yes, why not! We can use multiple router-outlets in the same template by configuring our routers and simply adds the router-outlet name.
<div class="row">
<div class="user">
<router-outlet name="users"></router-outlet>
</div>
<div class="detail">
<router-outlet name="userDetail"></router-outlet>
</div>
</div>
And setups your route config and it looks like this.
//Apps roots
const appRoots = [
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
{ path: 'userDetail', component: UserDetailComponent }, //Id is a Roots parameter.
{ path: 'users', component: UserComponent, data:{ title:'User List'} },
{ path: '**', redirectTo: 'PageNotFoundComponent' } //Wild Cards, the router will instantiate the PageNotFound component.
];
And
//AppModule class with @NgModule decorator
@NgModule({
//Composability and Grouping
//imports used for composing NgModules together
imports: [
BrowserModule,
//enableTracing is used for debugging purposes only
//Enables the location strategy that uses the URL fragment instead of the history API.
RouterModule.forRoot(appRoots)
],
//bootstrapped entry component
bootstrap: [AppComponent]
})
export class AppModule { }
What Is Router link?
The Router-link is a directive and it used to link a specific part of your applications.
@Directive({ selector: ':not(a)[routerLink]' })
Let explain the route configuration using the -
{ path: 'user/:id', component: UserDetailComponent
I the above rote configuration, when linking to this user/:id route, you use the RouterLink directive.
If the link is static, you can use the directive as follows.
<a routerLink="/user/id"> See the User detail</a>
If you using dynamic values to generate the router link that you can pass an array of path segments.
You can specify a route parameter like this.
<a [routerLink]="['/user', user.id]">
<span class="text-align">{{ user.id }}</span>{{ user.name }}
</a>
You can set query params and fragment as follows.
<a [routerLink]="['/user/id']" preserveQueryParams preserveFragment>
See the user component
</a>
You can specify optional route parameters like this.
<a [routerLink]="['/user-detail', { id: '102348014' }]">User Detail</a>
And
@Component({
selector: 'app-user',
template: `<nav>
<a [routerLink]="['/users']">User List</a>
<a [routerLink]="['/userDetail/101', { Id: '102348014' }]">User Detail</a>
</nav>
<router-outlet></router-outlet>`,
styleUrls: ['./user.component.css']
})
What Is RouterLinkActive?
The RouterLinkActive is a directive. To add the active CSS class to the element when the associated RouterLink becomes active (visually look like selected anchors). It is also works for both parent and child elements.
@Directive({
selector: '[routerLinkActive]',
exportAs: 'routerLinkActive'
})
Consider the following example for active a link –
<a routerLink="/user/detail" routerLinkActive="active-link">User Detail</a>
You can also set more than one class and it look like this.
<a routerLink="/user/detail" routerLinkActive="active-class1 active-class2">User detail</a>
<a routerLink="/user/detail" [routerLinkActive]="['active-class1', 'active-class2']">User detail</a>
What Is RouterState?
RouterState is interface and it represents the state of the router.
It looks like this.
interface RouterState extends Tree {
snapshot: RouterStateSnapshot
toString(): string
}
It is also a tree of activated routes.
We can access the current RouterState from anywhere in the Angular app using the Router service and the routerState property.
What Is ActivatedRoute?
ActivatedRoute is an interface and it contains the information about a route associated with a component loaded into an outlet and it can also be used to traverse the router state tree.
And it contains the list of Properties –
1. Snapshot – It is the current snapshot of this route.
2. URL – It is an observable of the URL segments and it matched by this route
3. Params – It is an observable of the matrix parameters scoped to this route
4. QueryParams - it is an observable of the query parameters shared by all the routes
5. Fragment- It is an observable of the URL fragment shared by all the routes
6. Data- It is an observable of the static and resolved data of this route.
7. Outlet. It's a constant and outlet name of the route
8. Component- It's a constant and a component of the route
9. RouteConfig- This configuration used to match this route
10. Root- This is the root of the router state
11. Parent - The parent of this route in the router state tree
12. FirstChild- The first child of this route in the router state tree
13. Children- The children of this route in the router state tree
14. pathFromRoot- The path from the root of the router state tree to this route
15. paramMap- It is read-only
16. queryParamMap- It is read-only
What Is Router events?
Whenever the root navigations, the router emits navigation events using Router.events property.
The sequence of router events is -
1. NavigationStart
2. RouteConfigLoadStart
3. RouteConfigLoadEnd
4. RoutesRecognized
5. GuardsCheckStart
6. ChildActivationStart
7. ActivationStart
8. GuardsCheckEnd
9. ResolveStart
10. ResolveEnd
11. ActivationEnd
12. ChildActivationEnd
13. NavigationEnd
14. NavigationCancel
15. NavigationError
The Router events are also logged in the console when enableTracing option is enabled.
The NavigationStart event is triggered when navigation starts.
The RoutesRecognized event triggered when the routes are recognized.
The RouteConfigLoadStart event triggered before the Router lazy loads.
The RouteConfigLoadEnd event triggered after a route has been lazily loaded.
The NavigationEnd event triggered when navigation ends successfully.
The NavigationCancel event triggered when navigation is canceled.
The NavigationError event triggered when router navigation fails due to an error.
For
more detail kindly refer the link - https://www.code-sample.com/2018/05/angular-5-6-7-routing-and-navigation.html