HI WELCOME TO SIRIS

Angular 2 route parameters

Leave a Comment

In this video we will discuss passing parameters to routes in Angular


Let us understand this with an example. We want to make Employee Code on Employee List component clickable.
Angular 2 route parameters



When we click on an Employee code, we want to redirect the user to Employee Component which displays that specific employee details. In the URL we will pass the emploee code as a parameter. So clicking on EMP101 will redirect the user to URL (http://localhost/employees/emp101). The Employee component will then read the parameter value from the URL and retrieves that specific employee details by calling the server side web service.
angular 2 route parameters example

In our previous video we have modified the code in app.module.ts file to use hash style routing. Let's remove useHash property, so we are using HTML5 style routing instead of hash style routing. Notice from the forRoot() method I have removed useHash property.
RouterModule.forRoot(appRoutes)

For HTML5 routing to work correctly, uncomment the following URL rewrite rule in web.config file of our Angular application.
<system.webServer>
  <rewrite>
    <rules>
      <rule name="Angular Routes" stopProcessing="true">
        <match url=".*" />
        <conditions logicalGrouping="MatchAll">
          <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
          <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
        </conditions>
        <action type="Rewrite" url="/src/" />
      </rule>
    </rules>
  </rewrite>
</system.webServer>

In the root application module (app.module.ts), include the following route. When the user navigates to a URL like (http://localhost:12345/employees/EMP101), we want to display EmployeeComponent. Notice the code parameter specified using colon (:).
{ path: 'employees/:code', component: EmployeeComponent }

Include the above route in appRoutes collection in app.module.ts file as shown below. Remember the order of the routes matter.

const appRoutes: Routes = [
    { path: 'home', component: HomeComponent },
    { path: 'employees', component: EmployeeListComponent },
    { path: 'employees/:code', component: EmployeeComponent },
    { path: '', redirectTo: '/home', pathMatch: 'full' },
    { path: '**', component: PageNotFoundComponent }
];

Next, in EmployeeListComponent, modify the <td> element that displays employee code to bind it to the route we created above using the routerLink directive as shown below. 

<td>
    <a [routerLink]="['/employees',employee.code]">
        {{employee.code | uppercase}}
    </a>

</td>

Explanation of the above code:
  • Notice in this example we are binding routerLink directive to an array.
  • This array is called link parameters array.
  • The first element in the array is the path of the route to the destination component.
  • The second element in the array is the route parameter, in our case the employee code.
In the Angular EmployeeService (employee.service.ts), introduce the following getEmployeeByCode() method. 

getEmployeeByCode(empCode: string): Observable<IEmployee> {
    return this._http.get("http://localhost:31324/api/employees/" + empCode)
        .map((response: Response) => <IEmployee>response.json())
        .catch(this.handleError);
}

Explanation of the above code:
  • This method takes employee code as a parameter and returns that employee object (IEmployee). 
  • This method issues a GET request to the Web API service. 
  • Once the Web API service returns the employee object, this method maps it to IEmployee type and returns it.
In one of our previous videos we have created EmployeeComponent to display employee details. When we created this component, we have hard coded employee data in the component itself. Now let's modify it
  • To retrieve employee details by calling the Angular EmployeeService method getEmployeeByCode() we created above.
  • This method calls the server side Web API service which retrieves that specific employee details from the database.
  • The employee code parameter is in the URL
  • To retrieve the parameter from the URL we are using the ActivatedRoute service provided by Angular 
  • Since ActivatedRoute is provided as a service inject it into the constructor just like how we have injected EmployeeService
employee.component.ts

import { Component, OnInit } from '@angular/core';
import { IEmployee } from './employee';
import { EmployeeService } from './employee.service';
import { ActivatedRoute } from '@angular/router';

@Component({
    selector: 'my-employee',
    templateUrl: 'app/employee/employee.component.html',
    styleUrls: ['app/employee/employee.component.css']
})
export class EmployeeComponent implements OnInit {
    employee: IEmployee;
    statusMessage: string = 'Loading data. Please wait...';

    constructor(private _employeeService: EmployeeService,
        private _activatedRoute: ActivatedRoute) { }

    ngOnInit() {
        let empCode: string = this._activatedRoute.snapshot.params['code'];
        this._employeeService.getEmployeeByCode(empCode)
            .subscribe((employeeData) => {
                if (employeeData == null) {
                    this.statusMessage =
                        'Employee with the specified Employee Code does not exist';
                }
                else {
                    this.employee = employeeData;
                }
            },
            (error) => {
                this.statusMessage =
                    'Problem with the service. Please try again after sometime';
                console.error(error);
            });
    }
}

employee.component.html

<table *ngIf="employee">
    <thead>
        <tr>
            <th colspan="2">
                Employee Details
            </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Employee Code</td>
            <td>{{employee.code}}</td>
        </tr>
        <tr>
            <td>Name</td>
            <td>{{employee.name}}</td>
        </tr>
        <tr>
            <td>Gender</td>
            <td>{{employee.gender}}</td>
        </tr>
        <tr>
            <td>Annual Salary</td>
            <td>{{employee.annualSalary}}</td>
        </tr>
        <tr>
            <td>Date of Birth</td>
            <td>{{employee.dateOfBirth}}</td>
        </tr>
    </tbody>
</table>
<div *ngIf="!employee">
    {{statusMessage}}
</div>

There are different approaches to retrieve route parameters values. We will discuss all the different approaches and when to use what in our upcoming videos.

Since we need EmployeeService both in EmployeeListComponent and EmployeeComponent, let's register it in the root module so we get a singleton instead of multiple instances of the service. 

We will discuss what is a Singleton in Angular and why is it important in our next video. For now, let's remove the EmployeeService registration from EmployeeListComponent by removing the following providers property in employeeList.component.ts file

providers: [EmployeeService]

Now regsiter the EmployeeService in application root module (app.module.ts) by including it in the providers property of @NgModule decorator as shown below

@NgModule({
    imports: [
        BrowserModule,
        OtherSystemModules..
    ],
    declarations: [
        AppComponent,
        OtherComponents..
    ],
    bootstrap: [AppComponent],
    providers: [EmployeeService]
})
export class AppModule { }

0 comments:

Post a Comment

Note: only a member of this blog may post a comment.