Monday, August 31, 2020

CanDeactivate Guard in Angular With Example

In this post we’ll see an example of CanDeactivate guard in Angular which helps in handling unsaved changes.

CanDeactivate interface in Angular

Any class implementing CanDeactivate interface can act as a guard which decides if a route can be deactivated. If you configure this class to be a canDeactivate guard for any route then if you try to navigate away from that route you can show a dialog box to confirm whether user really want to move away.

CanDeactivate interface has a single method canDectivate and the interface is defined as given below-

interface CanDeactivate<T> {
  canDeactivate(component: T, currentRoute: ActivatedRouteSnapshot, currentState: RouterStateSnapshot, nextState?: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree
}

Tuesday, August 25, 2020

Angular CanActivateChild Guard to protect Child Routes

In the post Angular Access Control CanActivate Route Guard Example we saw an example of canActivate guard and how it protects a route including its child routes. You can also protect child routes with the CanActivateChild guard in Angular. If you want to guard only the child component then you can use the CanActivateChild guard which is similar to the CanActivate guard with the difference that it runs before any child route is activated.

CanActivateChild interface in Angular

A class implementing CanActivateChild interface can act as a guard deciding if a child route can be activated. If all guards return true, navigation continues. If any guard returns false, navigation is cancelled.

There is one method canActivateChild in the interface.

interface CanActivateChild {
  canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree
}

Tuesday, August 18, 2020

Nested Route (Child Route) in Angular

All the Angular routing examples we have seen so far have routes that are relative to the root component. But in a big application you would want to contain the route with in another route that is creating routes that are relative to component other than root component. These types of routes with in a route are called nested route or child route in Angular routing.


How to create a child route in Angular routing

You place child routes in a children array within the parent route. For example if you want to create two nested routes relative to ParentComponent then it can be done as follows-

Monday, August 17, 2020

Functional Interfaces in Java

A functional interface in Java is an interface with only one abstract method. A functional interface is also known as SAM type where SAM stands for (Single Abstract Method). An example of functional interface with in Java would be Runnable interface which has only one method run().


Java functional interface example

interface IMyInterface {
  int getValue();
}

In interface IMyInterface there is only single abstract method getValue() (note that in an interface methods are implicitly abstract).

Setting Wild Card Route in Angular

In the post Angular Routing Concepts With Example we saw an example of setting up routes for navigation. One question though is what if user navigates to a path that does not exist. Ideally you should also handle such scenario and show a page not found or navigate to home page when user tries to navigate to a non-existent path. In this post we’ll see how to set up wild card route in Angular to handle any case when the requested URL doesn’t match any router path.

In this example wild card route is set up to show page not found message.

Wild card route in Angular

For setting up a wild card route in Angular you use ‘**’ (double asterisk). This wild card route catches all routes that are not configured with in the route definition.

{ path: '**', component: COMPONENT_NAME}

Do ensure that the wildcard route is the last one in the route definition ordering as wild card route matches every URL.

This order of routes is important because the Router uses a first-match wins strategy. When matching routes if wildcard route, which matches every URL, is at the top then the component paired with wildroute will be the one always called. Follow the order of-

  • List routes with a static path first.
  • Empty path route (with a possible redirection).
  • The wildcard route comes last.

Wild card route Angular Example

Routing module with route definitions including wild card route (app-routing.module.ts).

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: 'home', component: HomeComponent},                  
                      {path: 'account', component: AccountsComponent},
                      {path: 'account/:acctno', component: AccountComponent},
                      {path: 'service', component: ServiceComponent},
                      {path: '', redirectTo:'/home', pathMatch: 'full'}, 
                      {path: '**', component: PageNotFoundComponent}                
];

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

Do notice the route order, static paths first, then the default route redirect using empty path and then the wild card route.

PageNotFoundComponent (pagenotfound.component.ts)

@Component({
  selector: 'app-pagenotfound',
  templateUrl: './pagenotfound.component.html'
})
export class PageNotFoundComponent{

}

pagenotfound.component.html

<h3>404 Page Not Found!!</h3>

For other component’s code please refer this post- Angular Routing Concepts With Example

Now if you try to navigate any URL that doesn’t match any of the configured routes you will be sent to PageNotFoundComponent.

wild card route in Angular


That's all for this topic Setting Wild Card Route 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. Using RouterLinkActiveOptions to Fix Link Highlighted Problem
  3. Nested Route (Child Route) in Angular
  4. Angular Route Parameters - Setting and Fetching
  5. Passing Query Parameters in Angular Routing

You may also like-

  1. Angular ngFor Directive With Examples
  2. Angular One-Way Data Binding Using String Interpolation
  3. Angular Two-Way Data Binding With Examples
  4. Angular - Call One Service From Another
  5. ConcurrentHashMap in Java With Examples
  6. Var type in Java - Local Variable Type Inference
  7. What Are JVM, JRE And JDK in Java
  8. How to Write a Map Only Job in Hadoop MapReduce

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

Saturday, August 8, 2020

Switch Expressions in Java 12

In Java 12 Switch statement has been extended to be used either as a statement or an expression. In this article we’ll see with some examples how to use this new feature switch expressions in Java.


Java Switch expressions

A new form of switch label, written "case L ->" has been added in Java 12 that allows the code to the right of the label to execute only if the label is matched.

We’ll try to understand this switch expression with an example, initially let’s use traditional switch statement to write a conditional switch-case branch and then use switch expression to see how it simplifies it.

For example if you want to display the quarter, passed month falls into then you can group three case statements where break statement is used with only the last one in the group.

public class SwitchCaseDemo {

 public static void main(String[] args) {
  int month = 4;  
  switch(month){
   case 1:    
   case 2:    
   case 3: System.out.println("Quarter 1"); 
     break;
   
   case 4:   
   case 5:     
   case 6: System.out.println("Quarter 2"); 
     break;
   
   case 7:   
   case 8:  
   case 9: System.out.println("Quarter 3"); 
     break;
   
   case 10:     
   case 11:   
   case 12: System.out.println("Quarter 4"); 
      break;
   
   default: System.out.println("Invalid month value passed");
  }
 }
}

Consider some of the pain areas here-

  1. Even if multiple cases have the same end value still you need to write them in the separate lines.
  2. Use of many break statements make it unnecessarily verbose.
  3. Missing a break statement results in an accidental fall-through.

Now let’s write the same example using Java switch expressions.

public class SwitchCaseDemo {

  public static void main(String[] args) {
    int month = 4;        
    switch(month){
      case 1, 2, 3 -> System.out.println("Quarter 1");         

      case 4, 5, 6 -> System.out.println("Quarter 2");     
  
      case 7, 8, 9 -> System.out.println("Quarter 3");             
       
      case 10, 11, 12 -> System.out.println("Quarter 4");              
      
      default -> System.out.println("Invalid month value passed");
    }
  }
}

Note the changes here-

  1. Multiple case labels can be grouped together now.
  2. Break statement is not required any more. If a label is matched, then only the expression or statement to the right of an arrow label is executed; there is no fall through.
  3. This new switch form uses the lambda-style syntax introduced in Java 8 consisting of the arrow between the label and the code that returns a value.

Note that to use switch expressions feature make sure you have JDK 12 installed. To enable this feature, you’ll need to use the flags --enable-preview and --release 12 when you compile your code.

javac --enable-preview --release 12 SwitchCaseDemo.java

To run the generated class file, you’ll need to pass the --enable-preview flag to the Java launcher.

java --enable-preview SwitchCaseDemo

From Java 12 you can use colon syntax (:) too with multiple case labels but in that case break statement has to be used to avoid fall-through.

public class SwitchCaseDemo {

 public static void main(String[] args) {
  int month = 4;  
  switch(month){
   case 1, 2, 3 : System.out.println("Quarter 1"); 
         break;

   case 4, 5, 6 : System.out.println("Quarter 2");  
       break;
   case 7, 8, 9 : System.out.println("Quarter 3");    
       break;
   case 10, 11, 12 : System.out.println("Quarter 4");     
       break;
   default : System.out.println("Invalid month value passed");
  }
 }
}

Why is it called Switch expression

Now the more pertinent question is why this new feature is called switch expression. As you must be knowing; Statements are essentially “actions” that have to be executed. Expressions, however, are “requests” that produce a value. Same difference applies to switch statement and switch expressions too.

Here is an example showing returning a value from a traditional switch statement.

public class SwitchCaseDemo {
 public static void main(String[] args) {
  System.out.println(getMessage("Start"));
 }
 private static String getMessage(String event) {
  String message = "No event to log";
  switch (event) {
    case "Start":
      message = "User started the event";
      break;
    case "Stop":
      message = "User stopped the event";
      break;
  }
  return message;
 }
}

Output

User started the event

Same thing with Java Switch expressions. Since expression itself produces a value so it can be assigned to a variable directly.

public class SwitchCaseDemo {

 public static void main(String[] args) {
  System.out.println(getMessage("Start"));
 }
 private static String getMessage(String event) {
  var msg = switch (event) {
    case "Start" ->  "User started the event";
    case "Stop" -> "User stopped the event";
    default -> "No event to log";
  };
  return msg;
 }
}

Output

User started the event

If you want to use colon syntax then you can assign the value directly after break.

public class SwitchCaseDemo {

 public static void main(String[] args) {
  System.out.println(getMessage("Start"));
 }
 private static String getMessage(String event) {
  var msg = switch (event) {
    case "Start" : break  "User started the event";
    case "Stop" : break "User stopped the event";
    default : break "No event to log";
  };
  return msg;
 }
}

Writing statement blocks

If you need to have multiple statements with in a case you can use a statement block enclosed in curly braces.

public class SwitchCaseDemo {

  public static void main(String[] args) {
    int month = 4;        
    var value =switch(month){
      case 1, 2, 3 ->{
        System.out.println("Quarter 1");     
        break "Quarter 1";
      }
      case 4, 5, 6 -> {
        System.out.println("Quarter 2"); 
        break "Quarter 2";
      }
          
      case 7, 8, 9 ->{
        System.out.println("Quarter 3");     
        break "Quarter 3";
      }
               
      case 10, 11, 12 -> {
        System.out.println("Quarter 4");  
        break "Quarter 4";            
      }
              
      default -> {
        System.out.println("Invalid month value passed");
        break "Invalid month value";
      }
    };
    System.out.println("Value- " + value);
  }
}

That's all for this topic Switch Expressions in Java 12. If you have any doubt or any suggestions to make please drop a comment.Thanks!

>>>Return to Java Basics Tutorial Page


Related Topics

  1. break Statement in Java
  2. Type Wrapper Classes in Java
  3. Ternary Operator in Java
  4. Type Casting in Java
  5. Core Java Basics Interview Questions And Answers

You may also like-

  1. Private Methods in Java Interface
  2. Multi-Catch Statement in Java Exception Handling
  3. Creating a Thread in Java
  4. How HashMap Works Internally in Java
  5. Byte Streams in Java IO
  6. Check if Given String or Number is a Palindrome - Java Program
  7. Spring Boot Hello World Web Application Example
  8. Connection Pooling With Apache DBCP Spring Example

Friday, August 7, 2020

Using RouterLinkActiveOptions to Fix Link Highlighted Problem

In the post Highlight Currently Selected Menu Item Angular Routing Example we saw how you can highlight the selected menu option but there may be one problem with that, menu option configured with root path route always remain highlighted. In this post we’ll see how to fix the problem of root path route always remaining highlighted in Angular using routerLinkActiveOptions.

Link remaining highlighted problem

If you have configured your routes arrays something like as given below-

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

And the routeLink as given here-

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

Then you will see the problem of link associated with the root ("/") always remain highlighted.

Using routerLinkActiveOptions in Angular

You can see in the image even if Services menu link is clicked, ‘Home’ remains highlighted.

This problem occurs because Angular considers root path segment to be the part of all the paths. Even if path is either http://localhost:4200/service or http://localhost:4200/account, root path segment “/” is always there. That is the reason the Link associated with empty path (“/”) is always highlighted.

Using routerLinkActiveOptions

In order to solve this problem using routerLinkActiveOptions. With routerLinkActiveOptions you can pass a javascript object {exact:true} to direct Angular to make link active only when exact path matches.

<li class="nav-item" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">
  <a class="nav-link" routerLink="/">Home</a>
</li>

With this configuration change ‘Home’ menu will only be highlighted when it is selected, as soon as you move away from this option it won’t remain highlighted anymore.

That's all for this topic Using RouterLinkActiveOptions to Fix Link Highlighted Problem. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Angular Tutorial Page


Related Topics

  1. Angular Routing Concepts With Example
  2. Path Redirection in Angular Routing
  3. Navigate to a Route Programmatically in Angular
  4. Setting and Fetching Route Parameters in Angular
  5. Angular Two-Way Data Binding With Examples

You may also like-

  1. Angular ngClass Directive With Examples
  2. Angular Custom Event Binding Using @Output Decorator
  3. How to Add Bootstrap to Angular Application
  4. Angular - Call One Service From Another
  5. What is In-place Algorithm
  6. getPath(), getCanonicalPath() and getAbsolutePath() Methods in Java
  7. Switch Expressions in Java 12
  8. Python Exception Handling Tutorial

Thursday, August 6, 2020

Highlight Currently Selected Menu Item Angular Routing Example

In this article we’ll see how to highlight the currently selected menu item when using Angular routing and routerLink.

Note that Angular example shown here uses Angular 9 and Bootstrap 4.

RouterLink Directive in Angular

Angular RouterLink directive tracks whether the linked route of an element is currently active, it allows you to specify one or more CSS classes to add to the element when the linked route is active.

You can assign a CSS class as given below-

routerLinkActive="CSS_CLASS"
You can specify more than one CSS class using a space-separated string or an array.
routerLinkActive="CSS_CLASS1 CSS_CLASS2"

or

[routerLinkActive]="['CSS_CLASS1', 'CSS_CLASS2']"

Highlight currently selected menu item – Angular + Bootstrap example

In Bootstrap framework there is a CSS class active that can be used with routerLinkActive for the purpose of highlighting the selected menu item. Here is an example menu code.

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

That's all for this topic Highlight Currently Selected Menu Item Angular Routing Example. 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. Using RouterLinkActiveOptions to Fix Link Highlighted Problem
  3. Navigate to a Route Programmatically in Angular
  4. Nested Route (Child Route) in Angular
  5. Angular Two-Way Data Binding With Examples

You may also like-

  1. Angular Custom Two-Way Data Binding
  2. Angular @Input and @Output Example
  3. Angular - Call One Service From Another
  4. Creating New Component in Angular
  5. Pre-defined Functional Interfaces in Java
  6. Difference Between StackOverflowError and OutOfMemoryError in Java
  7. Writing a File Asynchronously Java Program
  8. Passing Arguments to getBean() Method in Spring

Wednesday, August 5, 2020

Path Redirection in Angular Routing

In this article we'll see how to redirect to a component (URL path) in Angular routing.


Setting redirect in Angular Routing

To set up a redirect in an Angular route definition you will have to use redirectTo property.

For redirection you need to configure a route with the following three things-

  1. path you want to redirect from
  2. The component you want to redirect to
  3. A pathMatch value to tell the router how to match the URL.

For example if you want to set a default route to the home page. When the initial URL in the browser is- localhost:4200 it should redirect automatically to localhost:4200/home.

{path: '', redirectTo:'/home', pathMatch: 'full'}

Here path you want to redirect from is '' meaning nothing after the base URL.

redirectTo has a value ‘/home’ which tells the Angular router when we visit path localhost:4200 redirect to the /home route.

Here pathMatch value is full which means redirection happens only if the full path after the base URL is ''.

Angular routing redirect example

Suppose we have three components Home, Account and Service and the app routing module is as given below.

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


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

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

As per route definition specified in routing module when URL has /home as path it will be handled by this route definition. HomeComponent is the component that will be called to handle this route.

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

Following route definition sets up a redirect to the above definition for home route if path matches '' (i.e. nothing after the base URL).

{path: '', redirectTo:'/home', pathMatch: 'full'},

Different path matching values

In the above route definition pathMatch value is used as ‘full’ which means value specified with path will be matched fully with the path after the base URL.

Another value for pathMatch is ‘prefix’ which tells the Angular to check if the path in the URL starts with the value given with path or not.

If you change the route definition to have pathMatch as prefix here-

{path: '', redirectTo:'/home', pathMatch: 'prefix'}

Now every path matches this route definition because technically every path starts with ''.

If you change the pathMatch to ‘prefix’, as per the route definitions given in the routing module in this example you will never be able to reach ServiceComponent because localhost:4200/service will always be matched by the redirect route. Other two routes above the redirect route will work fine because of the route ordering followed by Angular.

Route order in Angular

Angular uses the first-match wins strategy when matching routes so more specific routes should be placed above less specific routes.

  • Routes with a static path should be placed first.
  • Then an empty path route which matches the default route.
  • The wildcard route should be placed last because it matches every URL.

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

You may also like-

  1. Angular Custom Property Binding Using @Input Decorator
  2. Injector Hierarchy and Service Instances in Angular
  3. Angular Disable Button Example
  4. FormGroup in Angular With Examples
  5. Executor And ExecutorService in Java Concurrency
  6. Interface Default Methods in Java
  7. Bucket Sort Program in Java
  8. File Read in HDFS - Hadoop Framework Internal Steps

Monday, August 3, 2020

Angular Routing Concepts With Example

While writing any application we split it into different areas, UI is no different and you will have different web pages for different functionalities that will be derived, relative to the current URL, as an action to the event like clicking a button or a link. In Angular it is done using Angular routing where router enables navigation detecting change in browser URL as an instruction to change the view.

In this post we’ll go through an Angular routing example to understand how to configure routing and to understand different concepts related to the router.

Client side routing

In client side routing you don’t necessarily go to the server to get a new page. In Angular apps which are known as Single Page Apps (SPA) server gives us a single page and you change what the user sees by showing or hiding portions of the display that correspond to particular components. Read more about client side routing in this post- What is Client Side Routing in Angular.

Building blocks of Angular routing

  1. Import RouterModule and Routes into your routing module. Using Routes you configure the routes for your application.
  2. <router-outlet> element is a placeholder to inform Angular where to put the content for the selected route.
  3. RouterLink directive is used to create a link to navigate to a route.

Angular routing example

With the help of this Angular routing example we’ll see how to configure routing paths. There is a menu as shown below and you have to show the corresponding component on click of the menu option.

Angular routing

1. Creating routing module

We’ll create a separate routing file app-routing.module.ts

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


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

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

In this RoutingModule class you can notice the following things for routing-

  1. Import RouterModule and Routes into your routing module.
    import { Routes, RouterModule } from '@angular/router';
    
  2. Configure your routes in a Routes array by specifying the path and the component they are mapped to.
    const routes: Routes = [{path: '', redirectTo:'/home', pathMatch: 'full'},
                            {path: 'home', component: HomeComponent},
                            {path: 'account', component: AccountComponent},
                            {path: 'service', component: ServiceComponent}
                           ];
    

    Each route in this array is a JavaScript object containing two properties-

    • First property, path, defines the URL path for the route.
    • The second property, component, defines the component Angular should use for the corresponding path.

    There is also a redirect setup where path: '' means to use the initial relative URL and it defaults to the home route.

  3. Configures the imports and exports arrays for @NgModule(). In the RouterModule.forRoot() method you pass the routes array. This method creates and configures an NgModule with all the router providers and directives.

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

For menu styling Bootstrap 4 is used in the template.

To create a link to navigate to a given route, routerLink is used in Angular routing application rather than href. If you use href then clicking a link results in a page reload and that’s something you don't want in your single page apps. Using RouterLink directive to create a link to route doesn't cause full page reload.

<a class="nav-link" routerLink="/account">Accounts</a>

Value given here for routerLink should be same as how route path is configured in routes array in routing module.

routerLinkActive="active" ensures that the currently selected menu option is highlighted. Bootstrap framework is used in the example which already provides this active class so you don’t need to write this CSS class yourself.

In your single page apps you don’t want a full page reload you just want to substitute the content with the content of the selected route’s component. To inform Angular where do we want to render the contents for the selected, we use the RouterOutlet directive.

Placement of <router-outlet></router-outlet> defines where content will be rendered.

Another way to define routerLink

There is one more way to define a routerLink using property binding. If used this way you can pass the path segments as array elements. For example, if you want to define route to service using routerLink with property binding.

<a class="nav-link" [routerLink]="['/service']">Services</a>

Creating components

We are done with the configuration for Angular routing now we’ll go through the mapped components. Here focus is on understanding routing so data is hardcoded in the components.

Home Component (home.component.ts)

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

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

  ngOnInit() {
  }
}

home.component.html

<h4>Welcome to XYZ Bank</h4>
<p>{{ userId }} logged in.</p>

Account Component (account.component.ts)

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

@Component({
  selector: 'app-account',
  templateUrl: './account.component.html'
})
export class AccountComponent {
  accounts = [
    {
      accountnumber: 1001,
      type: 'Saving'
    },
    {
      accountnumber: 1002,
      type: 'Checking'
    }
  ];
}

account.component.html

<div class= "row">
  <div class="col-xs-4 col-md-6">
  <h2>Account Details</h2>
  <table class="table table-sm table-bordered m-t-4">
    <tr>
      <th>Account Number</th>
      <th>Account Type</th>
    </tr>
    <tr *ngFor="let account of accounts">
      <td>{{account.accountnumber}}</td>
      <td>{{account.type}}</td>
    </tr>
  </table>
  </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.

Running the application

Once the application is successfully compiled and you access it using http://localhost:4200 that redirects to the http://localhost:4200/home. Clicking on Home menu option also displays the same component.

Angular routing example

Clicking on Account menu option


Same way clicking on Service menu option displays the Service component.

That's all for this topic Angular Routing Concepts With Example. 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 Wild Card Route in Angular
  4. Using RouterLinkActiveOptions to Fix Link Highlighted Problem
  5. Passing Query Parameters in Angular Routing

You may also like-

  1. Angular Custom Two-Way Data Binding
  2. Angular @Input and @Output Example
  3. Angular - Call One Service From Another
  4. Creating New Component in Angular
  5. Pre-defined Functional Interfaces in Java
  6. Difference Between StackOverflowError and OutOfMemoryError in Java
  7. Writing a File Asynchronously Java Program
  8. Passing Arguments to getBean() Method in Spring