Skip to main content

Angular Routing Compete Guide

 Routes can be added at 2 place

1. In routing file - app-routing.module.ts

2. Any Module file like - app.module.ts file 


1. In routing file - app-routing.module.ts

1. If we define in any module then we have to create a const like this 


This appRoute should be specific type of Routes and this should be imported from 


This should hold a array because we will have multiple routes and we will add all the routes to this array and each route is just a javascript object in this array. 

But question is how such route should be configured in angular app. It should follow some specific pattern or specific structure to angular use it. and this structure always need a path 

path: this is what is mentioned in url after your domain name and this should be string. Like it could be users route so it should be like this  {path: 'users'} 

common mistake is that never add / in the starting route like {path:'/users'}


When you reach this what should happen if we don't define then nothing will happen so next is 

component: by defining this we are just informing angular that whenever you reach this path you should load this component. and this component could be a page that can be loaded.


We can define this way multiple routes like this way.


 But that alone don't do anything. So how would angular know that you want to use this constant. We can add any constant instead of appRoutes but how angular knows that you want to use these routes. so these routes will be ignore by angular until you register with angular app and we do this by adding new import in imports array. We need to import RouterModule in imports :[] array and it should be imported from router package as RouterModule like this.

import {Routes, RouterModule} from '@angular/router';




But by doing this still our routes are not yet registered so our RouterModule has special method forRoot() and we can pass our constant appRoutes of type Routes that we defined in this method. This allow us to register some route to our main application by doing this now registered with angular app on this router module which gives us routing functionality now angular knows our routes. 

But missing piece is  to render currently selected component so take a example if you click on http://localhost:4200/users

so where to load this users component so how it knows where to display it. now you don't add your component with selector but you will add a special  directive <router-outlet></router-outlet> this simply marks the place in our document where we want angular router to load this component of the currently selected route.


Now important part is how to register link in html so we can use 

<a href="/users">Users</a>

so we use href="/users" so by doing this actually we are loading full page and request sent to server and whole page get loaded. so its break single page behaviour 

so we should not implement this behaviour so we should use different behaviour  we will use special directive called routerLink="/users"

<a routerLink="/users">Users</a>

we can also do by using property binding as well

like this <a [routerLink]="/users">Users</a>

Or

like this <a [routerLink]="['/users']">Users</a>

If we specify / in the starting of routerLink then it means its absolute path.

<a [routerLink]="['users']">Users</a>

But think if we don't use / before the path then what happens 

Suppose we are don't specify then it will append to current path like suppose we are on path http://localhost:4200/users and we don't specify / then it will append to this url as next and it might give error also so always think carefully. 


How to add dynamically css class to anchor tag <a>

Angular gives us specific directive called routerLinkActive="define_css_class_name_here"

like this way 

<a routerLink="/users" routerLinkActive="active">Users</a>

<a routerLink="/services" routerLinkActive="active">Services</a>

<a routerLink="/products" routerLinkActive="active">Products</a>


We have to define this routerLinkActive to all my links should receive this active css class once they are clicked or active. 

But here we can also define some cases like 

<a routerLink="/products" routerLinkActive="active" [routerLinkActiveOptions]="{exact:true}">Users</a>

[routerLinkActiveOptions]="{exact:true}" it means this routerLinkActive="active" will work only if this is exact path otherwise it will not work.



Navigating Programatically. 

Like some case we don't have link so that user can click but we finish some operation or user click some button then we want trigger some navigation from our typescript code. We can do this 

lets say our home component i add to button called load servers we can add routerLink but we want this programatically so we will attach a event listener called click listener, and execute some method. 





like <button class="btn btn-success" (click)="onLoadServers()">Load servers </button>

now this method we have to implement in typescript file. 

onLoadServers(){

// complex calcuation like do server operation after that we can navigate to customer another page 


}


But to do so we need access of router some how we get this so 

Step 1. import Router from @angular/router package. like this way

 


Step 2. Inject router in constructor 


Step 3. Now we have to use this router in our method in which we want to use this. 

like - this.router.navigate()

navigate method and it takes argument which allows us to navigate to new route. But here route is defined as array ['here we can define new path'] like as we mentioned above we can pass different type of ways for routerlink so similar we can do here  



In this image we are using absolute path like this this.router.navigate(['/services']); but we don't use / in front of services still it will work and it will not give any error like we did in html like if in html if we don't define then it will attach that path to current route but here it if we are on service route and still don't define / then it wont get any error because angular don't know the current route. 

Note: Unlike routerLink navigate method doesn't know on which currently on. routerLink always knows in which component it shit which component templates so it know what currently loaded route is 

So in case if we need to know and want to define route relative to particular route then we have to follow some steps. 

Step 1. First we need to know current route so we have to import new module called 

import {Router, ActivatedRoute} from '@angular/router';

Step 2. We have to inject route in constructor as follow 

constructor(private route: ActivatedRoute){}

Note: ActivatedRoute inject only currently active route

if we want to know currently at which component we are so we have to pass second argument in naviagte method which is basically a javascript object 

this.route.navigate(['serviers'], {relativeTo: this.route})

here we are telling that relativeTo this route you have to navigate this route. 



Passing Parameters to Routes 

Step 1 : Define dynamic path in Routes array we can do this by adding : and then any name you like. And later it will be retrieved by this name in the loaded component. 

like {path: 'users/:id', component: UserComponent},



If we don't define : column then it would be considered as normal string but if we define column : then it will be considered as dynamic path

Note: We are passing id to UserComponent so we have to access this id in this component.

Fetching Route Parameters

Step: 2 - To get current route we have to import ActivatedRoute from @angular.router package

import {ActivatedRoute} from '@angular/router';

Step: 2 - To get current route we have to inject ActivatedRoute in constructor. 

constructor(private route: ActivatedRoute){}


Step 3 : Fetch values in ngOnInIt() method


snapshot vs params

If we use snapshot and load data by using snapshot  object on route  and if we load new route then what happens angular will look into our app.module or routing file  and angular look fitting route and load component and initialise component and gives the data by accessing snapshot  but only happen when we are not on this component before. means we are coming from different component then only we will get. 

If we are already on that component and we want some action from same component then url will change but data will not reflect because angular will not reinstate this component because angular know we are already on that component because if we are already on that component they why angular re render this component but we want to get updated data based on url then we can use another method instead of snapshot method on route. 

We can initialise data from snapshot but to listen subsequent changes  we need different  approach we can use params property on route object.  But this params is observable so it will listen and work as async events which happen in future then we can execute code which happens  and this subscribe method takes 3 functions as argument  

Fetching Route Parameters Reactively

 

Note: If we know our component never be reloaded within that component as we are doing in below image  then we might not need this addition subscription  we will use snapshots. 

But if we are calling from the some component and we are loading within the component we have to use and listen for subscription and url changes. 




Note: Once we close this component subscription will not destroyed once component destroyed so this subscription will be in memory. We can store this subscription in some property and we can destroy this subscription manually but it will be done automatically by angular  but if we add our own observable then we have to unsubscribe  this way mentioned below image. 


Step 1: First import Subscription from rxjs package. 


  

Step 2 : 



Passing Query Parameters and Fragments


How to pass you can pass them using angular links (routerLinks) and how we can retrieve them.

Fragements - are used by # in url to jump to specific place in our app.

Step 1. Define in Routes array 

const appRoutes: Routes = [
{path : 'servers/:id/edit', component: EditServerComponent},
];




[queryParams] = "{}" this is another bindable property of routerLink. Which used to pass values through query parameters. Here we have to pass javascript object

and similar we also have  Fragment property
fragment="loading"

Note: [routerLink] we use [] bracket around to routerLink if we want to pass array like this 

[routerlink]="['/servers', 5,  'edit']" If we want to pass query parameter then we don't do ?= in this routerLink we have different element for query parameter - queryParams we have this property for binding query parameters like shown in above image. Similar we can pass fragment.


How can i do this programatically


 
Like in earlier concept we shown relative to navigate method similar we can also pass javascript object by defining {queryParams:{allowEdit: '1'}, fragment: 'loading'} to this navigate method.


Retrieving Query Parameters and Fragments


So how we can get access to query parameter ? 

Step 1 : First we need ActivatedRoute for this so we have to import this from angular router package and inject to constructor. 




Step2 : Inside ngOnInit() {} method we can retrieve query parameters and fragment. Just like before there are 2 ways to fetch these. using snapshot and subscription. 

Lets talk on snapshot first. 

But if we use this.route.snapshot.queryParams or this.route.snapshot.fragement then this might bring some problem as with params (means path parameter we have seen above case.)  Because this is only run and updated at the time this component get created if is there any chance to changing query params from the page currently on you might not want this approach because it won't be reactive.
in reactive way we have to just use queryParams instead of params 

like this. -- > this.route.queryParams.subscribe(); or this.route.fragement.subscribe();




Note: Whenever we fetch params from url or queryParams from url we can store them in const variable like this ways. or we can also store by created a javascript object and another way mentioned above. 

like this way. -   const id = this.route.snapshot.params['id'];

Note: If we parse parameter from url it will always be string. Because our whole url is text. So it return as string and suppose we are passing this as number then it might create a problem so first we have to convert from string to number by adding + sign in front of fetched string. 

const id = +this.route.snapshot.params['id'];


Note : If we have parent component which is let loaded on top component by using router-outlet but if we have child component of this parent component then it should be loaded inside the parent then we have to define again router-outlet for child also because it can't be loaded on parent so we have to define separate router-outlet.




2. Any Module file like - app.module.ts file 

imports : [RouterModule.forRoot(appRoute)] this is not sufficient because as i mentioned we simply want to use this approutemodule outsource these routes there for we need to add AppRoutingModule to main module for this we need to exports:[] this module.  









Comments

Popular posts from this blog

How do I change the time zone of my Amazon RDS database instance?

As we know bydefault time in the format of UTC in mysql.We can set local time zone to our AWS RDS Instance for our application. or any other time zone prefared Cloud Based Website Hosting Service Provider Steps 1: Go to Services and Select RDS Now to change time zone we have to change "Parameter Group" in left side that is associated with DB instance first we can check default Parameter Group for our instance is Parameter group default.mysql5.7  ( in-sync ) like this. So we have to change the time zone in this Parameter Group.  now open that parameter group (default.mysql5.7)  and click on edit parameter. then search for time_zone (because we want to change it.) then we have to change time_zone only by default it is engine-default (that is utc)  we have to select Asia/Calcutta.  More information we can ref.  https://aws.amazon.com/premiumsupport/knowledge-center/rds-change-time-zone/

Changing the Time Zone on Amazon Linux Ec2 Instance

Amazon Linux instances are set to the UTC (Coordinated Universal Time) time zone by default, but you may wish to change the time on an instance to the local time or to another time zone in your network. Important These procedures are intended for use with Amazon Linux. For more information about other distributions, see their specific documentation. To change the time zone on an instance Identify the time zone to use on the instance. The  /usr/share/zoneinfo  directory contains a hierarchy of time zone data files. Browse the directory structure at that location to find a file for your time zone. [ec2-user ~]$ ls /usr/share/zoneinfo Africa Chile GB Indian Mideast posixrules US America CST6CDT GB-Eire Iran MST PRC UTC Antarctica Cuba GMT iso3166.tab MST7MDT PST8PDT WET Arctic EET GMT0 Israel Navajo right W-SU ... Some of the entries at this location are directo

Amazon EC2 Server Setup & Installing JDK 8 and Tomcat 8, Running on Port 80 & 443 and Redirect Request from port 80 to 8080 and 443 to 8443

Amazon EC2 Server Setup & Installing JDK 8 and Tomcat 8, Running on Port 80 & 443 and Redirect Request from port 80 to 8080 and 443 to 8443. Step 1 : Log in to your aws account by following this link then click on my account and choose option aws management console. Note: I am assuming you created your account with aws and you are ready with you account if you haven’t done then you can check out on google you will get many and it's a straight forward steps if you have still problem while creating an account you can comment in comment box i will also provide tutorial for that. Once you logged in aws management console you are able to see window like this one Note : Before we go ahead we have to select proper reason from right and side. I choose ohio region for this example. Step 2 : Now you have to choose EC2 Server from Services tab on left side top corner then choose EC2 Services from “Compute option ” You will get window like this one and r