In this blog article, we will discuss about sending user events from Child Component to Parent Component using @Output() decorator, @EventEmitter and ng-container directive.
Read my previous blog article Angular Component Input Properties before proceeding this article.
Continuing the previous artilce, at the moment when we click the radio buttons, nothing happens. Let us load the table based on the radio button filtering by courses.
Step 1: Update the child.component.ts
class like below.
- Here we have imported Output and EventEmitter from @angular/core.
- Now add string property as
selectedRadioButtonValue: string = 'All'
- Add
@Output() childEvent = new EventEmitter()
- Add
@Output() countRadioButtonSelectionChanged: EventEmitter = new EventEmitter()
- Add event method
onRadioButtonSelectionChange()
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
@Input() all: number;
@Input() python: number;
@Input() angular: number;
selectedRadioButtonValue: string = 'All';
@Output() childEvent = new EventEmitter();
@Output() countRadioButtonSelectionChanged: EventEmitter<string> =
new EventEmitter<string>();
constructor() { }
onRadioButtonSelectionChange() {
this.countRadioButtonSelectionChanged
.emit(this.selectedRadioButtonValue);
}
ngOnInit() {
}
}
Now update the child.component.html
as below
- Here we have added
[(ngModel)]
to all the input radio buttons. Implemented 2 way data-binding using the ngModel directive. ngModel is bound toselectedRadioButtonValue
property in the component class. This 2 way data-binding ensures whenever the radio button selection changes, the selectedRadioButtonValue property is updated with the value of the selected radio button. Insideapp.module.ts
file Import Forms module from ‘@angular/forms’ and add in imports. [(ngModel)] only works after importing Forms Module. - Added change event
onRadioButtonSelectionChange()
for all input radio buttons. onRadioButtonSelectionChange() method is binded to “change” event of the radio button. Whenever, the selection of the radio button changes, onRadioButtonSelectionChange() method raises the custom eventcountRadioButtonSelectionChanged
and we have created this using EventEmitter.
<span class="radioClass">Show : </span>
<input name='options' type='radio' value="All"
[(ngModel)]="selectedRadioButtonValue"
(change)="onRadioButtonSelectionChange()"
>
<span class="radioClass">{{'All(' + all + ')'}}</span>
<input name="options" type="radio" value="Python"
[(ngModel)]="selectedRadioButtonValue"
(change)="onRadioButtonSelectionChange()"
>
<span class="radioClass">{{"Python(" + python + ")"}}</span>
<input name="options" type="radio" value="Angular"
[(ngModel)]="selectedRadioButtonValue"
(change)="onRadioButtonSelectionChange()"
>
<span class="radioClass">{{"Angular(" + angular + ")"}}</span>
Step 2: Now update the parent.component.ts
file as below
- Here we have added
selectedCourseCountRadioButton
string - Added
onCourseCountRadioButtonChange()
method onCourseCountRadioButtonChange($event)
method is bound to the custom event – countRadioButtonSelectionChanged. The $event object will have the selected radio button value as that is passed as the event payload from the nested component. The event handler method (onCourseCountRadioButtonChange()) in the component class updates the property “selectedCourseCountRadioButton”. This property is then used with *ngIf structural directive to decide which Course objects to display in the table.
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
selectedCourseCountRadioButton: string = 'All';
constructor() {
this.courses = [
{
coursecode: 'PY', coursename: 'Python', fee: 5500, student: 'Girish'
},
{
coursecode: 'NG', coursename: 'Angular', fee: 3000, student: 'Santosh'
},
{
coursecode: 'NG', coursename: 'Angular', fee: 3000, student: 'Sanjay'
},
{
coursecode: 'PY', coursename: 'Python', fee: 3000, student: 'Ramesh'
},
{
coursecode: 'PY', coursename: 'Python', fee: 5500, student: 'Ganesh'
},
{
coursecode: 'PY', coursename: 'Python', fee: 5500, student: 'Govind'
}, {
coursecode: 'PY', coursename: 'Python', fee: 5500, student: 'Gopal'
},
{
coursecode: 'PY', coursename: 'Angular', fee: 5500, student: 'Saravana'
},
];
}
getTotalCourseCount(): number {
return this.courses.length;
}
getPythonCourseCount(): number {
return this.courses.filter(e => e.coursename === 'Python').length;
}
getAngularCourseCount(): number {
return this.courses.filter(e => e.coursename === 'Angular').length;
}
onCourseCountRadioButtonChange(selectedRadioButtonValue: string): void {
this.selectedCourseCountRadioButton = selectedRadioButtonValue;
}
ngOnInit() {
}
}
Now update the parent.component.html
as below
- Here we have added
countRadioButtonSelectionChanged
event to child component - Added
ng-container
to the table row to use the structural directives (*ngFor and *ngIf)
<app-child [all]="getTotalCourseCount()"
[python]="getPythonCourseCount()"
[angular]="getAngularCourseCount()"
(countRadioButtonSelectionChanged)="onCourseCountRadioButtonChange($event)"
>
</app-child>
<br /><br />
<table>
<thead>
<tr>
<th>Code</th>
<th>Name</th>
<th>Fee</th>
<th>Student</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let course of courses;">
<tr *ngIf="selectedCourseCountRadioButton=='All' ||
selectedCourseCountRadioButton==course.coursename">
<td>{{course.coursecode }}</td>
<td>{{course.coursename }}</td>
<td>{{course.fee}}</td>
<td>{{course.student}}</td>
</tr>
</ng-container>
<tr *ngIf="!courses || courses.length==0">
<td colspan="5">
No courses to display
</td>
</tr>
</tbody>
</table>
Now you can see the updates in the table whenever we select the relavant radio buttons.
References
- https://angular.io/guide/template-syntax#input-and-output-properties
Learn more about Angular features in the next upcoming blog articles.
Happy Learning!