Support us .Net Basics C# SQL ASP.NET Aarvi MVC Slides C# Programs Subscribe Download

Passing data between components in angular

Suggested Videos
Part 55 - Angular router navigation events | Text | Slides
Part 56 - Angular route loading indicator | Text | Slides
Part 57 - Angular canactivate guard example | Text | Slides

In this video we will discuss different ways of passing data between components.


There are several techniques to pass data between components in angular. We discussed most of these techniques in our previous videos in this series. If the components are nested, then there is a parent child relationship between those components. To pass data from the parent to child component we use input properties. To pass data from the child component to parent component we can either use output properties or template reference variables.


Passing data from Parent Component to Child Component
Input Properties Part 21 - Angular 2 tutorial

Part 33 - Angular CRUD tutorial

Passing data from Child Component to Parent Component
Output Properties Part 22 - Angular 2 tutorial

Part 37 - Angular CRUD tutorial
Template Reference Variables Part 38 - Angular CRUD tutorial

Passing data from Component to Component (No parent child relation)
Angular Service Part 34 - Angular 2 tutorial
Required Route Parameters Part 40 - Angular CRUD tutorial
Optional Route Parameters Part 43 - Angular CRUD tutorial
Query Parameters Part 51 - Angular CRUD tutorial

Let's use some of these techniques to pass data between components. Along the way we will refactor the code in the angular application that we have been working with so far in this video series. 

This will give us little more practice with component communication techniques. We are refactoring code in our application in preparation for performing DELETE and UPDATE operations in our upcoming videos. By the end of this video, our Employee List page should be as shown below.

angular project tutorial

Changes in list-employees.component.html
  • Remove the style property on "Search By Name" text box so the width spans 100%
  • Remove "Change Employee Name" button along with the <div> element that surrounds it
  • Delete changeEmployeeName() method in the component class (list-employees.component.ts)
  • #childComponen template reference variable is not required on <app-display-employee> child componenet. So delete it.
  • Remove the <div> element that surrounds <app-display-employee> child component.
  • Delete "onClick(employee.id)" method in the component class (list-employees.component.ts)
  • Delete (mousemove) event binding and the corresponding method in the component class
  • We want to pass the Search Term we type in the "Search By Name" textbox to the child component DisplayEmployeeComponent. So notice on <app-display-employee> we are binding to searchTerm input property. We do not have this searchTerm input property DisplayEmployeeComponent yet. We will implement that in just a bit.
At this point, the HTML in list-employees.component.html file should be as shown below
<div class="form-group">
    <input type="text" class="form-control"
           placeholder="Search By Name" [(ngModel)]="searchTerm" />
</div>
<div *ngFor="let employee of filteredEmployees">
    <app-display-employee [employee]="employee" [searchTerm]="searchTerm">
    </app-display-employee>
</div>

In list-employees.component.ts file we are not using the Router service anymore. So remove it from the import statement and the constructor. At this point the code in list-employees.component.ts should be as shown below.
import { Component, OnInit } from '@angular/core';
import { Employee } from '../models/employee.model';
import { ActivatedRoute } from '@angular/router';

@Component({
  templateUrl: './list-employees.component.html',
  styleUrls: ['./list-employees.component.css']
})
export class ListEmployeesComponent implements OnInit {
  employees: Employee[];
  filteredEmployees: Employee[];

  private _searchTerm: string;
  get searchTerm(): string {
    return this._searchTerm;
  }
  set searchTerm(value: string) {
    this._searchTerm = value;
    this.filteredEmployees = this.filtereEmployees(value);
  }

  filtereEmployees(searchString: string) {
    return this.employees.filter(employee =>
      employee.name.toLowerCase().indexOf(searchString.toLowerCase()) !== -1);
  }

  constructor(private _route: ActivatedRoute) {

    this.employees = this._route.snapshot.data['employeeList'];

    if (this._route.snapshot.queryParamMap.has('searchTerm')) {
      this.searchTerm = this._route.snapshot.queryParamMap.get('searchTerm');
    } else {
      this.filteredEmployees = this.employees;
    }

  }

  ngOnInit() {
  }
}

Changes in display-employee.component.html file : Include a panel footer. The HTML required for the panel footer is shown below. Paste this HTML just before the last closing </div> element in display-employee.component.html file.
<div class="panel-footer">
  <button class="btn btn-primary" (click)="viewEmployee()">View</button>
  <button class="btn btn-primary">Edit</button>
  <button class="btn btn-danger">Delete</button>
</div>

Changes in display-employee.component.css file : Include the following style for the View, Edit and Delete buttons so all of them have the same width.
button.btn {
    width: 70px;
}

Changes in display-employee.component.ts file : Include searchTerm input properrty. This is the property to which the parent component (ListEmployeesComponent) is binding ans passing the searchTerm we have typed in the "Search By Name" textbox.

Also, include viewEmployee() method. This is the method that is called when "View" button is clicked.
import { Component, OnInit, Input } from '@angular/core';
import { Employee } from '../models/employee.model';
import { ActivatedRoute, Router } from '@angular/router';

@Component({
  selector: 'app-display-employee',
  templateUrl: './display-employee.component.html',
  styleUrls: ['./display-employee.component.css']
})
export class DisplayEmployeeComponent implements OnInit {
  @Input() employee: Employee;
  @Input() searchTerm: string;

  private selectedEmployeeId: number;

  constructor(private _route: ActivatedRoute, private _router: Router) { }

  ngOnInit() {
    this.selectedEmployeeId = +this._route.snapshot.paramMap.get('id');
  }

  viewEmployee() {
    this._router.navigate(['/employees', this.employee.id], {
      queryParams: { 'searchTerm': this.searchTerm }
    });
  }
}

Changes in employee-details.component.html file : Modify "Back to List" button as shown below. Notice we have removed [queryParams] directive. We included this [queryParams] directive to demonstrate merging query parameters. Also set queryParamsHandling to preserve instead of merge.
<a class="btn btn-primary" [routerLink]="['/list',{id:employee.id}]"
   queryParamsHandling="preserve">
    Back to List
</a>

Changes in app.component.html file : In the menu we do not need "Get Employee with Id 2" link. So remove the associated menu item.

In our upcoming videos we will discuss implementing UPDATE and DELETE operations.

angular crud tutorial

1 comment:

  1. Please create a series on ASP.NET Identity Framework...i'm waiting for your response whether its positive or negative for creating series on identity framework

    ReplyDelete

It would be great if you can help share these free resources