a blog for those who code

Tuesday 12 March 2019

Understanding Routing in Angular


Routing is one of the important aspects of any Web Application be it a single page app or a multi-page application. Angular uses Angular Router (@angular/router package) which enables the navigation from one view to other as and when users perform any tasks. Angular Router provides a routing library which helps in maintaining multiple router outlets, access to route parameters and route guards which helps to protect the route from unauthorized access.

The main aim of routing in Angular or more specifically Single Page Applications is that it enables the developers to show multiple views and allow the navigation between these views based on users interaction.

The Basics of Angular 7


At first we will be adding the Routing Module (AppRoutingModule) which will contain our application routes and a router outlet where Angular framework will insert the matched component depending on the browser URL.

app-routing.module.ts


import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { NotFoundComponent } from './notfound/notfound.component';

const routes: Routes = [
  {
    path: '',
    component: HomeComponent
  }, {
    path: '**',
    component: NotFoundComponent
  }
];
@NgModule({
  imports: [RouterModule.forRoot(routes)],   exports: [RouterModule] }) export class AppRoutingModule { } 

The app-routing.module.ts will contain the above code where we have used @NgModule decorator which is used to create an Angular module. The decorator also takes some meta information like imports and exports. In the imports attribute we call the RouterModule.forRoot(routes) method with the routes as a parameter to register our routes for the main application and thus making our routes known to Angular Framework and in the exports we are just exporting the RouterModule.

In the above code we have created two routes, one with the empty path and onw with the wildcard path. The empty path means that when we navigate to the base url (localhost:4200) the HomeComponent will be routed to. The wildcard path will match any unrecognized path and show the NotFoundComponent. 

Note : You also have to add this module to the main app module under imports as :

imports: [
  // All other imports,
  AppRoutingModule
]

Next is to add <router-outlet></router-outlet> to app.component.html file where the Angular Router will render the component based on the routes. Router-Outlet is a directive where the Router inserts the component that gets matched in the Routes based on the browser's URL. 

Now we have the routes in place as well as we have rendered them on the component, thus we now need some mechanism to navigate to that routes. This is where the routerLink directives will come into picture which when added on the anchor tags will take the user to that rout when clicked.

<a routerLink="/route">My Route</a>

When to use [routerLink] or routerLink in Angular


You can also write routes without '/' i.e. relative path and it will be of same behavior on the home component but on the child component you might get error like "Error: Cannot match any routes" this is because it appends the path you have specified in teh routerLink to the path already exists.

For Example: If you are in http://localhost:4200/route and in that component you have a reload page which has an anchor tag as <a routerLink="route">Reload Page</a>, it will try to navigate to http://localhost:4200/route/route because route is being appended to the existing url which is not in the case of using <a routerLink="/route">My Route</a> because it appends '/route' after the base URL.

The router supports different type of syntax as below :

./ or no leading slash is relative to the current path i.e. it appends the route to the current URL path.
../ to go one level up and then append to the path

We also have a RouterLinkActive directive which lets you add a CSS class based on which link's route is active. 

<a routerLink="/route" routerLinkActive"active">My Route</a>

Whenever the url is /route it will add an "active" class to my anchor tag if teh url will change the class will be removed. We can also add routerLinkActiveOptions which will only add the class when the url matches the link exactly as shown below

<a routerLink="/route" 
   routerLinkActive"active"
   [routerLinkActiveOptions]="{exact: true}"
>My Route</a>

Till now we have learned how we can have an anchor tag and add routerLink which will make the anchor tag as a navigate path, but what if we want to do it programatically. To navigate through programatically we need to use Angular Router and navigate to some route as shown below

export class MyComponent {
  constructor(private router: Router) {}
  onNavigate() {
    this.router.navigate(['/route'])
  }
} 

We can also pass parameters to the route and fetch those parameters in our TypeScript code. For passing we have to use colon syntax, which creates a slot in the path for a Route Parameter as shown below 

{ path: 'home/:id', component: HomeComponent}

To fetch the parameters we will use ActivatedRoute which contains information about a route associated with a component loaded as shown below. 

export class MyComponent implements OnInit {
  constructor(private router: Router, private route: ActivatedRoute) {}
  ngOnInit() {
    let id = this.route.snapshot.paramMap.get('id');
  }
  onNavigate() {
    this.router.navigate(['/route'])
  }
} 

We can also use QueryParameters in our route as shown below 

<a routerLink="/route" [queryParams]="{isEdit: true}">My Route</a>

OR

this.router.navigate(['/route'], { queryParams: { isEdit: true } });

So we have successfully covered the basics of Routing in Angular, in our next post we will be discussing about Guards.

No comments:

Post a Comment