Monday, August 10, 2020

Navigate to a Route Programmatically in Angular

In this post we’ll see how to navigate to a route programmatically or dynamically using router.navigate() or router.navigateByUrl() methods in Angular.

Navigating to a route dynamically Angular example

You may have a scenario where you would like to navigate to a route based on an event like click of a button, clicking a link. Here is a simple example which uses router.navigate() method to navigate to a route on a click of a button.

There is a menu as shown below and you have to show the corresponding component on click of the menu option.

1. Creating routing module

We’ll create a separate routing file app-routing.module.ts with routes array to define route paths and component they map to.

import { NgModule } from '@angular/core';
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: '', component: HomeComponent},                  
                        {path: 'account', component: AccountsComponent},
                        {path: 'service', component: ServiceComponent}
                       ];

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

2. Import the AppRoutingModule into AppModule (app.module.ts) and add it to the imports array.

import { AppRoutingModule } from './app-routing.module';
imports: [
  BrowserModule,
  AppRoutingModule
],

3. Adding the configured routes to the application.

Code for menu and adding link for routes is done in the app.component.html template itself for this example.

<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" [routerLinkActiveOptions]="{exact: true}">
          <a class="nav-link" routerLink="/">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>

Creating components

Now as per our route mapping there are 3 components HomeComponent, AccountsComponent and ServiceComponent.

Home Component (home.component.ts)

From the home page you want to provide a button to take to AccountsComponent. That route navigation will be done programmatically.

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

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html'
})
export class HomeComponent implements OnInit {
  userId = 'UID0023';
  constructor(private router: Router) { }

  ngOnInit() {
  }

  navigateToAccount(){
    this.router.navigate(['/account']);
  }
}

To use Router.navigate method first you need to inject the Router class in your component. That is done in the constructor.

In the method navigateToAccount(), router.navigate() method is used to navigate to a route. In navigate method you pass an array of elements that are joined together to create a path. For example router.navigate(‘account’, 1) resolves to a path /account/1.

If you want to use router.navigateByUrl() method then you can also use this.router.navigateByUrl('/account'); With router.navigateByUrl() you can pass an absolute path, for example router.navigateByUrl(‘/account/1’).

Note that in this example path passed in this.router.navigate(['/account']); is an absolute path (not relative).

home.component.html

<h4>Welcome to XYZ Bank</h4>
<p>{{ userId }} logged in.</p>
<div>
    <button type="button" class="btn btn-primary" (click)="navigateToAccount()">My Accounts</button>
</div>

Account Component (account.component.ts)

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

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

accounts.component.html

<div class= "row">
  <div class="col-xs-4 col-md-6">
    <h2>Account Numbers</h2>
    <!-- [routerLink]="" 
    (click)="onAccountClick(account)" -->
    <div class="list-group">
      <a class="list-group-item"   
        *ngFor="let account of accounts">
        {{ account }}
      </a>
    </div>
  </div>
</div>

Service Component (service.component.ts)

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

@Component({
  selector: 'app-service',
  templateUrl:'./service.component.html'
})
export class ServiceComponent{
  services = [
    'Deposit Money',
    'Open FD',
    'Mail Customer Care'
  ]; 
}

service.component.html

<h2>Services Offered</h2>
<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>

Add these components in the declarations array of the AppModule before running the example.

You will have a button in the HomeComponent which navigates you to the AccountsComponent when clicked.

Navigate to a Route Programmatically in Angular

Dynamic route Navigation using relative path in Angular

In the previous example we used absolute path with navigate() method but you can also pass a relative path but in that case you need to specify path is relative to which existing path.

Let’s change the previous example to have one more component AccountComponent that shows the details for the account selected in AccountsComponent.

For that routes array will have to be changed in the following way-

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

As you can see a new route definition is added- {path: 'account/:acctno', component: AccountComponent}, here :acctno is a placeholder that matches any account number so URL like account/A001 or account/A002 both will match this route.

Accounts component is also changed-

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

@Component({
  selector: 'app-accounts',
  templateUrl: './accounts.component.html'
})
export class AccountsComponent {
  accounts = ['A1001', 'A1002'];
  constructor(private router: Router, private route: ActivatedRoute) {}
  onAccountClick(account: string){
    this.router.navigate([account], {relativeTo:this.route});
  }
}

Along with Router class now ActivatedRoute class is also injected into the component. ActivatedRoute class provides access to information about a route associated with a component that is loaded in router outlet.

In router.navigate() method you can also pass a second argument of type navigationExtras. One of the NavigationExtras is relativeTo which specifies a root URI to use for relative navigation.

In the example navigate method is now like this-

this.router.navigate([account], {relativeTo:this.route});

Here this.route specifies the route associated with the component, in our case it will be /account so relative path is http://localhost:4200/account

[account] specifies the account number that is clicked which can be either A1001 or A1002. Thus the navigation route is derived as either http://localhost:4200/account/A1001 or http://localhost:4200/account/A1002 which matches the route definition {path: 'account/:acctno', component: AccountComponent}.

AccountComponent (account.component.ts)

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } 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 route: ActivatedRoute){ }
  accountDetails = [
    {
      accountnumber: 'A1001',
      type: 'Saving', 
      balance: 22000
    },
    {
      accountnumber: 'A1002',
      type: 'Checking',
      balance: 1000
    }
  ];

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

Here we have defined an account type- account: {accountnumber: string, type: string, balance: number};

There is also an array with values for account.

In ngOnInit() using the passed account number we find the related object in the array using the find() method.

Account number parameter is extracted from the route using the current snapshot of the route.

this.route.snapshot.params['acctno'];

account.component.html

<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>

Accounts Component

Account Component

navigating route dynamically angular

That's all for this topic Navigate to a Route Programmatically in Angular. 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. Highlight Currently Selected Menu Item Angular Routing Example
  3. Setting and Fetching Route Parameters in Angular
  4. Setting Wild Card Route in Angular
  5. Nested Route (Child Route) in Angular

You may also like-

  1. Angular Custom Two-Way Data Binding
  2. Angular @Input and @Output Example
  3. Angular Event Binding With Examples
  4. Angular ngFor Directive With Examples
  5. Java Lambda Expression And Variable Scope
  6. Serialization and Deserialization in Java
  7. String Slicing in Python
  8. How to Untar a File - Java Program

No comments:

Post a Comment