Friday, August 14, 2020

Passing Query Parameters in Angular Routing

In this post we’ll how to pass query parameters in Angular routing and how to retrieve the passed query parameters.


Query parameters in Angular

Using query parameters you can pass optional parameters across the routes in your application. Query parameters are separated by a question mark from the URL and any route parameters. You can have more than one query parameter in the URL which are separated by &.

For example- localhost:4200/services?accttype=s&allowaccess=1

Here accttype and allowaccess are query parameters.

Passing query parameters in Angular routing

1. You can pass query parameters with RouterLink directive. RouterLink directive has a property queryParams that is used to pass query parameters.

<a [routerLink]="['/account', accountnumber]"  
            [queryParams]="{accttype: 's'}"           
             class="list-group-item"   
            *ngFor="let accountnumber of accountnumbers">
            {{ accountnumber }}
</a>

Which results in a URL like- http://localhost:4200/account/A1001?accttype=s

2. You can also pass query parameters programmatically using Router.navigate() method. In navigate method you can pass query parameters as a Javascript object.

this.router.navigate(['/account', accountno], {queryParams:{accttype: 's'}});

You can of course pass more than one query parameter in both of these ways as comma separated values.

this.router.navigate(['/account', accountno], {queryParams:{accttype: 's', allowaccess: 1}});

Accessing query parameters in Angular

For retrieving query parameters in Angular you can use the queryParams property of the ActivatedRoute class.

this.route.queryParams
          .subscribe((queryParams: Params)=> {
            this.acctType = queryParams['accttype']
          });
or you can use the current snapshot of the route to get query parameters from that.
this.acctType = this.route.snapshot.queryParams['accttype'];

Query parameters in Angular routing example

Let’s see a full Angular example to understand passing and retrieving of query parameters. In the example there is-

AccountsComponent to display account numbers.

AccountComponent to display details of the clicked account.

In the AccountComponent there is a button to navigate to ServiceComponent which displays the offered services only if account type is saving. Account type is passed as a query parameter.

1. Routing module (app-routing.module.ts)

import { Routes, RouterModule } from '@angular/router';
import { AccountsComponent } from './accounts/accounts.component';
import { AccountComponent } from './accounts/account/account.component';
import { HomeComponent } from './home.component';
import { ServiceComponent } from './service.component';

const routes: Routes = [
                    {path: 'home', component: HomeComponent},                  
                    {path: 'account', component: AccountsComponent},
                    {path: 'account/:acctno', component: AccountComponent},
                    {path: 'service', component: ServiceComponent},
                    {path: '', redirectTo:'/home', pathMatch: 'full'}             
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

2. Adding routing module to AppModule.

import { AppRoutingModule } from './app-routing.module';

imports: [
  BrowserModule,
  AppRoutingModule
],

3. Route links (app.component.html)

<nav class="navbar navbar-expand-md bg-dark navbar-dark">
  <div class="container-fluid">
    <div class="collapse navbar-collapse" id="collapsibleNavbar">
      <ul class="nav navbar-nav">
        <li class="nav-item" routerLinkActive="active">
          <a class="nav-link" routerLink="/home">Home</a>
        </li>
        <li class="nav-item" routerLinkActive="active">
          <a class="nav-link" routerLink="/account">Accounts</a>
        </li>
        <li class="nav-item" routerLinkActive="active">
          <a class="nav-link" [routerLink]="['/service']">Services</a>
        </li>
      </ul>
    </div>
  </div>
</nav>
<div class="container">
  <div class="row"><p></p></div>
  <div class="row">
    <div class="col-md-12">
      <router-outlet></router-outlet>
    </div>
  </div>
</div>

4. Creating components.

AccountsComponent (accounts.component.ts)

In this component there are some hardcoded account numbers.

import { Component } from '@angular/core';

@Component({
  selector: 'app-accounts',
  templateUrl: './accounts.component.html'
})
export class AccountsComponent {
  accountnumbers = ['A1001', 'A1002'];
}

accounts.component.html

This template displays the account numbers and also creates route link for account numbers.

<div class= "row">
  <div class="col-xs-4 col-md-6">
    <h2>Account Numbers</h2>
    <div class="list-group">
      <a [routerLink]="['/account', accountnumber]"           
        class="list-group-item"   
        *ngFor="let accountnumber of accountnumbers">
        {{ accountnumber }}
      </a>
    </div>
  </div>
</div>

AccountComponent (account.component.ts)

In this component we display details for the account number which is sent as route parameter. To extract the parameter route.params observable is used and we subscribe to it so that when ever there is a change the parameter is extracted into a acctNo variable. This is done in ngOnInit().

Using the fetched account number we find the related object in the array using the find() method.

There is also a onSelectedAccount(acct) method where the query parameter is attached to the URL in the router.navigate() method.

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params, Router } from '@angular/router';

@Component({
  selector: 'app-account',
  templateUrl: './account.component.html'
})
export class AccountComponent implements OnInit{
  acctNo: string;
  account: {accountnumber: string, type: string, balance: number};
  constructor(private router: Router, private route: ActivatedRoute){ }
  accountDetails = [
    {
      accountnumber: 'A1001',
      type: 'Saving', 
      balance: 22000
    },
    {
      accountnumber: 'A1002',
      type: 'Checking',
      balance: 1000
    }
  ];

  ngOnInit() {
    this.route.params.subscribe((params: Params)=> this.acctNo = params['acctno']);
    this.account = this.accountDetails.find(e=>e.accountnumber === this.acctNo);
  }

  onSelectedAccount(acct){
    this.router.navigate(['/service'], {queryParams:{accttype: acct.type === 'Saving'? 's':'c'}})
  }
}

account.component.html

This template displays the account details for the selected account number. There is also a button to navigate to the offered services for the selected account number.

<h2>Account Details</h2>
<div class="row">
  <div class="col-xs-6">
    <label>Account Number: </label> {{ account.accountnumber }}
  </div>
</div>
<div class="row">
  <div class="col-xs-6">
    <label>Account Type: </label> {{ account.type }}
  </div>
</div>
<div class="row">
  <div class="col-xs-6">
    <label>Balance: </label> {{account.balance}}
  </div>
</div>
<button class="btn btn-primary" (click)="onSelectedAccount(account)">Offered Services</button>

ServiceComponent (service.component.ts)

In this component we have the offered services stored in an array. In the ngOnInit() method passed query parameter (accttype) is retrieved using route.queryParams observable.

Boolean variable showServices is assigned the value true or false based on whether the passed query parameter is ‘s’ or ‘c’.

import { Component, OnInit } from "@angular/core";
import { ActivatedRoute, Params } from '@angular/router';

@Component({
    selector: 'app-service',
    templateUrl:'./service.component.html'
})
export class ServiceComponent implements OnInit{
  showServices = false;
  services = [
    'Deposit Money',
    'Open FD',
    'Mail Customer Care'
  ];
  constructor(private route : ActivatedRoute){ }
  ngOnInit() {
    this.route.queryParams
              .subscribe((queryParams: Params) => {
                  this.showServices = queryParams['accttype'] === 's'? true:false
               });
  }
}

service.component.html

Using ngIf directive value of showServices is checked and if it is false then the messsage ‘No services for checking account’ is displayed otherwise offered services are displayed.

<h2>Services Offered</h2>
<h4 *ngIf="!showServices">No services for checking account</h4>
<div *ngIf="showServices">
  <div class="row">
    <div class="col-xs-12 col-sm-6">
      <div class="list-group">
        <a
          href="#"
          class="list-group-item"
          *ngFor="let service of services">
          {{ service }}
        </a>
      </div>
    </div>
  </div>
</div>

Showing account numbers-

Display account details-

Offered services-

When URL is- http://localhost:4200/service?accttype=s

When URL is- http://localhost:4200/service?accttype=c

Preserving or Merging Query Parameters with queryParamsHandling

If you navigate away from the route with query parameters to any other route, by default the query parameters are lost. If you want to retain them set queryParamsHandling to-

  • preserve- If you want to preserve the original query parameters.
  • merge- If you want to merge the original query parameters with the new one.

For example if you want to move from service to other-page and still want to keep the query parameters-

onClickOtherPage(){
  this.router.navigate(['/other-page'], {queryParamsHandling:'preserve'});
}

Resulting in a URL- http://localhost:4200/other-page?accttype=s

If you want to add more query parameters and want to retain the previous one too-

onClickOtherPage(){
  this.router.navigate(['/other-page'], {queryParams: {param1: 'value', queryParamsHandling:'merge'});
}

Resulting in a URL- http://localhost:4200/other-page?param1=value&accttype=s

That's all for this topic Passing Query Parameters in Angular Routing. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Angular Tutorial Page


Related Topics

  1. Path Redirection in Angular Routing
  2. Navigate to a Route Programmatically in Angular
  3. Angular Route - Passing Static Data
  4. Location Strategies in Angular Routing
  5. Angular Custom Property Binding Using @Input Decorator

You may also like-

  1. Angular Custom Two-Way Data Binding
  2. Angular ngSwitch Directive With Examples
  3. Angular Cross Component Communication Using Subject Observable
  4. FormBuilder in Angular Example
  5. PriorityBlockingQueue in Java Concurrency
  6. Difference Between StackOverflowError and OutOfMemoryError in Java
  7. Predefined Mapper And Reducer Classes in Hadoop
  8. Passing Arguments to getBean() Method in Spring

No comments:

Post a Comment