Passing Query Parameters To Route In Angular
In this article, we will learn how to pass and access Optional or query parameters in Angular. Query parameters allow you to send optional parameters to the component, such as the page number. In this article, we'll look at how to use the queryParams directive to pass query parameters. The ActivatedRoute Service is then used to obtain the parameter in the component.
What are query parameters?
Query parameters are parameters that you can send to a route as an option. The query parameters are separated by a question mark and placed at the end of the URL.
For Example
/product?page=2
If the query argument is page=2
The URL above is an example of a paginated product list, where the URL signals that the second page of the product list should be loaded.
Difference between Query parameter and Route parameter
The route parameters are needed, and Angular Router uses them to calculate the route. They're included in the route's definition.
The id is the route parameter, for example, when we define the route as given below.
{ path: 'product', component: ProductComponent } { path: 'product/:id', component: ProductDetailComponent }
The above-mentioned path corresponds to the following URL: The angular fields 1 and 2 are mapped to the id field by the angular.
URL
/product matches => path: 'product' /product/1 matches => path: 'product/:id' /product/2 matches => path: 'product/:id'
If the id is not provided, the Router will not travel to the ProductDetailComponent route. Instead, it will go to ProductComponent. There will be an error if the product route is not defined.
The query parameters, on the other hand, are optional. The lack of a parameter has no effect on the angular's ability to navigate to the route. The query parameters are separated by a question mark and placed at the end of the URL.
Route Parameters or Query Parameters?
- When a value is necessary, use the route parameter.
- When the value is optional, use the query parameter.
How to use Query Parameters
The route does not include the query parameters. As a result, they aren't defined in the routes array like route parameters. You can use the routerlink directive or the router.navigate function to add them.
Passing Query Parameters
To add the query parameter, use the queryParams directive. As illustrated below, use this directive in conjunction with the routerlink directive.
<a [routerLink]="['product']" [queryParams]="{ page:2 }">Page 2</a>
The URL will be constructed as /product?pageNum=2 by the router.
As demonstrated below, you can pass several Query Parameters.
<a [routerLink]="['product']" [queryParams]="{ val1:2 , val2:10}">Whatever</a>
The URL will be constructed as /product? by the router. val1=2&val2=10
You can also use the Router service's navigate method to navigate programmatically, as illustrated below.
goToPage(pageNum) { this.router.navigate(['/product'], { queryParams: { page: pageNum } }); }
Reading Query Parameters
It's equivalent to reading the Router Parameter to read the Query Parameter. The query parameters can be retrieved in one of two methods.
Using queryParamsMap observable
The queryParamsMap is an Observable that holds a map of the query parameters that the current route supports. This can be used to get values from query parameters. ActivatedRoute provides access to the queryParamsMap.
As a result, we must inject the ActivatedRoute in the constructor of the component/service where the query parameter is to be read, as seen below.
constructor(private Activatedroute:ActivatedRoute, private router:Router){ }
You can subscribe to the ActivatedRoute's queryParamMap, which returns a paramMap observable. The query parameter can then be read using the get method, as demonstrated below.
this.sub = this.Activatedroute.queryParamMap .subscribe(params => { this.pageNum = +params.get('pageNum')||0; });
Using snapshot.queryParamMap property
The snapshot property of the ActivatedRoute can also be used to read the value of the query parameter from queryParamMap, as demonstrated below.
this.Activatedroute.snapshot.queryParamMap.get('pageNum')||0;
queryParamsHandling
When the user switches routes, the query parameter is lost.
For example, if a user navigates to the product page using the route /product?pageNum=2 and subsequently to the product detail page, the query parameter is removed from the url by angular. This is how things work by default.
The queryParamsHandling technique can be used to adjust this behaviour. When the user navigates away from the current route, this Configuration strategy controls how the angular router handles query parameters. There are three alternatives available.
This is the default setting. When moving to the next page, angular removes the query parameter from the URL.queryParamsHandling : null
this.router.navigate(['product'], { queryParams: { pageNum: this.pageNo + 1 }, queryParamsHandling :null} );
<a [routerLink]="['product']" [queryParams]="{ pageNum:2 }">Page 2</a>
queryParamsHandling : preserve
The query parameter of the current route is preserved or carried forward to the next navigation by Angular. The next route's query parameters are discarded.
this.router.navigate(['product'], { queryParams: { pageNum: this.pageNo + 1 }, queryParamsHandling :"preserve"} );
<a [routerLink]="['product']" [queryParams]="{ pageNum:2 }" queryParamsHandling="preserve">Page 2</a>
queryParamsHandling : merge
Before travelling to the next route, Angular blends the query parameters from the current route with those from the next route.
this.router.navigate(['product'], { queryParams: { pageNum: this.pageNo + 1 }, queryParamsHandling :"merge"} );
<a [routerLink]="['product']" [queryParams]="{ pageNum:2 }" queryParamsHandling="merge">Page 2</a>
Query Params Example
Let's make a simple application to show how to use query parameters.
Let's make some changes to the app we created in the Passing Parameters to Route article. From the "Parameters" folder and the "QueryParameters" code.
Add the following code under the app.component.ts file:
import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'Routing Module - Query Parameters'; pageNum=0; }
Add the following code under the app.component.html file:
<div class="container"> <nav class="navbar navbar-default"> <div class="container-fluid"> <div class="navbar-header"> <a class="navbar-brand" href="#"><strong> {{title}} </strong></a> </div> <ul class="nav navbar-nav"> <li><a [routerLink]="['home']">Home</a></li> <div class="navbar-form navbar-left"> <div class="form-group"> <input type="text" class="form-control" placeholder="Page No" [(ngModel)]="pageNum"> </div> </div> <li class="nav"><a [routerLink]="['product']" [queryParams]="{ pageNum: pageNum }">Product</a></li> <li><a [routerLink]="['contact']">Contact us</a></li> </ul> </div> </nav> <router-outlet></router-outlet> </div>
The pageNum variable has been defined in the component. A pageNum input box is given so that the user can adjust the page number.
The navigation Menu is part of the AppComponent. It has a link to the product page on it. The routerlink directive is used to build the link. The queryParams directive in the routerlink directive is where we provide the pageNum to the "pageNum" variable.
<li class="nav"><a [routerLink]="['product']" [queryParams]="{ pageNum: pageNum }">Product</a></li>
The URL will be constructed as /product?pageNum=2 by Angular.
Product Component
There are no products displayed in the ProductComponent. However, it shows the query parameters that were sent.
Add the following code under the product.component.ts file:
import { Component, OnInit } from '@angular/core'; import { ActivatedRoute, Router} from '@angular/router'; @Component({ templateUrl: './product.component.html', }) export class ProductComponent implements OnInit { pageNo=0; snapshotPageNo=0; constructor(private Activatedroute:ActivatedRoute, private router:Router){ } ngOnInit() { // the following code works but is DEPRECATED // this.snapshotPageNo =this.Activatedroute.snapshot.queryParams['pageNum']||0; // this.Activatedroute.queryParams // .subscribe(params => { // this.pageNo = +params['pageNum']||0; // console.log('Query params ',this.pageNo) // }); this.snapshotPageNo =+this.Activatedroute.snapshot.queryParamMap.get('pageNum')||0;; this.Activatedroute.queryParamMap .subscribe(params => { this.pageNo = +params.get('pageNum')||0; console.log('Query params ',this.pageNo) }); } nextPage() { this.router.navigate(['product'], { queryParams: { pageNum: this.pageNo + 1 }} ); } }
Add the following code under the product.component.html file:
<h1>Product Page</h1> <p>Current Page No <strong> {{pageNo}} </strong></p> <p>snapshot Page No <strong> {{ snapshotPageNo }} </strong></p> <button (click)="nextPage()">Next Page</button>
To begin, we've injected both ActivatedRoute and Router Service into the ProductComponent's constructor.
constructor(private Activatedroute:ActivatedRoute, private router:Router){ }
We then use the Activatedroute.snapshot function to extract the pageNum and update the snapshotPageNo variable in the ngOnInit lifecycle hook.
The queryParams property is also subscribed to. The page number obtained from the Queryparams is updated in our local variable pageNo.
Both snapshotPageNo and pageNo variables are displayed in our template.
ngOnInit() { this.snapshotPageNo = this.Activatedroute.snapshot.queryParams['pageNum'] || 0; this.Activatedroute.queryParams .subscribe(params => { this.pageNum = +params['pageNum']||0; console.log('Query params ',this.pageNum) }); }
We also have a method called nextPage.
nextPage() { this._router.navigate(['./'], { queryParams: { pageNum: this.pageNum + 1 }, relativeTo: this._Activatedroute } ); }
To browse to the next page, we use the router.navigate method. We are already on the page, therefore this does not modify the route. The angular router does not recreate the component, but we will be notified of the change in page Number because we have subscribed to the Query parameters. The pageNum variable is changed to reflect the new value, while the snapshotPageNo variable remains unchanged.
Add the following code under the app.module.ts file:
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; import { RouterModule } from '@angular/router'; import { AppComponent } from './app.component'; import { HomeComponent} from './home.component' import { ContactComponent} from './contact.component' import { ProductComponent} from './product.component' import { appRoutes } from './app.routes'; @NgModule({ declarations: [ AppComponent,HomeComponent,ContactComponent,ProductComponent ], imports: [ BrowserModule, FormsModule, HttpModule, RouterModule.forRoot(appRoutes) ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Add the following code under the app.routes.ts file:
import { Routes } from '@angular/router'; import { HomeComponent} from './home.component' import { ContactComponent} from './contact.component' import { ProductComponent} from './product.component' export const appRoutes: Routes = [ { path: 'home', component: HomeComponent }, { path: 'contact', component: ContactComponent }, { path: 'product', component: ProductComponent }, { path: '', redirectTo: 'home', pathMatch: 'full' }, ]; home.component.ts import {Component} from '@angular/core'; @Component({ template: `<h1>Welcome!</h1> <p>This is Home Component </p> ` }) export class HomeComponent { }
Add the following code under the contact.component.ts file:
import {Component} from '@angular/core'; @Component({ template: `<h1>Contact Us</h1> <p>TekarticlesHub </p> ` }) export class ContactComponent { }
Run the application, type in the page number, and then click the Product Link.
Conclusion
In this article, we learned how to pass and access Optional or query parameters in Angular.
I hope this article helps you and you will like it.👍
If you have any doubt or confusion then free to ask in the comment section.