Angular 2 @Input and @Output Example
November 24, 2016
This page will walk through angular 2 @Input and @Output example. @Input is a decorator to mark an input property and @Output is a decorator to mark an output property.
@Input
is used to define an input property to achieve component property binding. @Output
is used to define output property to achieve custom event binding. @Input
and @Output
can define alias for property names as @Input(alias)
and @Output(alias)
. Here on this page we will provide a complete example of @Input
and @Output
decorators. We are creating a parent component and two child components. We will perform component property binding and custom event binding using both the child components. In our example we will use @Input
with different data types such as string, number, array and user defined class. @Output
will be used with the instance of EventEmitter
. Now find the complete example step by step.
Contents
Software Used
Find the software used in our demo.1. Angular 2.3.0
2. TypeScript 2.0.10
3. Node.js 4.6.0
4. NPM 3.10.8
5. Firefox 50.1.0
@Input
@Input
decorator binds a property within one component (child component) to receive a value from another component (parent component). This is one way communication from parent to child. The component property should be annotated with @Input
decorator to act as input property. A component can receive a value from another component using component property binding. Now we will see how to use @Input. It can be annotated at any type of property such as number, string, array or user defined class. To use alias for the binding property name we need to assign an alias name as @Input(alias)
.
Find the use of
@Input
with string data type.
@Input() ctMsg : string;
@Input
decorator. Here we are aliasing the property name. In the component property binding, alias name ctArray
will be used.
@Input('ctArray') myctArray : Array<string>
@Input
decorator with a property of user defined class type.
@Input('stdLeader') myStdLeader : Student;
@Output
@Output
decorator binds a property of a component to send data from one component (child component) to calling component (parent component). This is one way communication from child to parent component. @Output
binds a property of the type of angular EventEmitter
class. This property name becomes custom event name for calling component. @Output
decorator can also alias the property name as @Output(alias)
and now this alias name will be used in custom event binding in calling component.
Find the
@Output
decorator using aliasing.
@Output('addStudentEvent') addStdEvent = new EventEmitter<Student>();
addStudentEvent
will become custom event name. Now find @Output
decorator without aliasing.
@Output() sendMsgEvent = new EventEmitter<string>();
sendMsgEvent
will be custom event name.
Aliasing Input and Output properties
@Input
and @Output
decorate input and output properties. @Input
can alias input property name and @Output
can alias output property name.
1. Aliasing input property using @Input
To alias input property use an alias as
@Input(alias)
. Find code snippet.
<child-two [stdLeader] = "stdLeaderObj"> </child-two>
stdLeaderObj
is the property of parent component. stdLeader
is the alias of child component property. Now find the below ode snippet.
@Input('stdLeader') myStdLeader : Student;
stdLeader
is the alias of myStdLeader
property.
2. Aliasing output property using @Output
To alias output property use alias as
@Output(alias)
. Find the custom event binding as below.
<child-two (addNumberEvent) = "printSum($event)" > </child-two>
addNumberEvent
is a custom event name. When this event will invoke, printSum()
method will be executed. Now find the code snippet.
@Output('addNumberEvent') addNumEvent = new EventEmitter<number>();
addNumberEvent
is the alias of addNumEvent
.
Component Property Binding using @Input
Find the steps for component property binding using@Input
decorator step by step.
1. In the parent component, first create a property. Here we are creating a property of our class
Student
type.
stdLeaderObj = new Student('Narendra', 'Modi');
<child-two [stdLeader] = "stdLeaderObj"> </child-two>
@Input
decorator to declare child component property as an input property that will receive value from parent using component property binding. Here we are using aliasing for property name.
@Input('stdLeader') myStdLeader : Student;
{{myStdLeader.fname +' '+ myStdLeader.lname}}
Custom Event Binding using @Output and EventEmitter
Here we will discuss custom event binding using@Output
decorator step by step.
1. Create text box using element property binding in child component.
input
event is fired when there is any change in text box. $event.target.value
fetches the current value of text box entered by user.
<div> First Number :<input (input)="num1=$event.target.value" /> <br/> Second Number:<input (input)="num2=$event.target.value" /> <br/> <br/> <button (click)="addNumber()">Add Number</button> </div>
click
event is invoked on click of button from above (step-1) code snippet. emit()
is the method of EventEmitter
class that emits event payload.
addNumber() { this.addNumEvent.emit(parseInt(this.num1) + parseInt(this.num2)); }
EventEmitter
annotated by @Output
decorator. This instance will work as custom event name. Here we are using aliasing for custom event name.
@Output('addNumberEvent') addNumEvent = new EventEmitter<number>();
addNumberEvent
will be invoked in parent component when emit()
method is invoked from child component. The event payload is accessed by $event
object.
<child-two (addNumberEvent) = "printSum($event)" > </child-two>
addNumberEvent
will call printSum()
method.
printSum(res) { this.sum = res; }
Complete Example using TypeScript
We will provide a complete example of@Input
and @Output
decorator using TypeScript. In our example we will create a parent component and two child component. Both child will use @Input
and @Output
decorator.
student.ts
export class Student { constructor(public fname?: string, public lname?: string) { } }
?
in constructor parameter. By using question mark ?
in constructor parameter, we achieve that while creating instance of Student
class, passing arguments are optional. And it is possible to create instance of our Student
class as new Student()
without passing any argument. If we do not use question mark ?
in constructor parameters, new Student()
will through error and requires arguments.
parent.component.ts
import {Component} from '@angular/core'; import {Student} from './student'; @Component({ selector: 'input-output', template: ` <h1>{{parentTitle}}</h1> <child-one [ctMsg]="cityMsg" [ctArray]="cityArray" [studentAddMsg]="stdAddMsg" (addStudentEvent) = "saveData($event)" (sendMsgEvent) = "printMsg($event)" > </child-one> <p>Name: {{stdFullName}}</p> <p>Message: {{msg}}</p> <child-two [studentMsg] = "stdMsg" [stdLeader] = "stdLeaderObj" (addNumberEvent) = "printSum($event)" > </child-two> <p>Sum: {{sum}}</p> ` }) export class ParentComponent { parentTitle = 'Parent Component'; //Property for child component one cityMsg = 'Indian City Names'; cityArray = ['Varanasi', 'Delhi', 'Mumbai']; stdAddMsg = 'Add Student'; //Property for child component two stdMsg = 'Student Leader Detail'; stdLeaderObj = new Student('Narendra', 'Modi'); //Property used in parent stdFullName = ''; sum = ''; msg = ''; saveData(std) { this.stdFullName = std.fname + ' ' + std.lname ; } printSum(res) { this.sum = res; } printMsg(msg) { this.msg = msg; } }
import {Component, EventEmitter, Input, Output} from '@angular/core'; import {Student} from './student'; @Component({ selector: 'child-one', template: ` <h3>{{childTitle}}</h3> <b> {{ctMsg}}</b> <ul> <li *ngFor = "let cname of myctArray"> {{cname}} </li> </ul> <b>{{addMsg}}</b><br/> <div> First Name:<input (input)="student.fname=$event.target.value" /> <br/> Last Name:<input (input)="student.lname=$event.target.value" /> <br/> <button (click)="addStudent()">Add Student</button> </div> <br/><b>{{message}}</b><br/> <div> Message :<input (input)="msg=$event.target.value" /> <br/> <button (click)="sendMsg()">Send</button> </div> ` }) export class ChildOneComponent { @Input() ctMsg : string; @Input('ctArray') myctArray : Array<string> @Input('studentAddMsg') addMsg : string; @Output('addStudentEvent') addStdEvent = new EventEmitter<Student>(); @Output() sendMsgEvent = new EventEmitter<string>(); student = new Student(); childTitle = '---Child One---'; message = 'Send Message' msg : string; addStudent() { this.addStdEvent.emit(this.student); } sendMsg() { this.sendMsgEvent.emit(this.msg); } }
import {Component, EventEmitter, Input, Output} from '@angular/core'; import {Student} from './student'; @Component({ selector: 'child-two', template: ` <h3>{{childTitle}}</h3> <p> {{studentMsg}} : {{myStdLeader.fname +' '+ myStdLeader.lname}} </p> <b>{{addNumMsg}}</b><br/> <div> First Number :<input (input)="num1=$event.target.value" /> <br/> Second Number:<input (input)="num2=$event.target.value" /> <br/> <br/> <button (click)="addNumber()">Add Number</button> </div> ` }) export class ChildTwoComponent { @Input() studentMsg : string; @Input('stdLeader') myStdLeader : Student; @Output('addNumberEvent') addNumEvent = new EventEmitter<number>(); childTitle = '---Child Two---'; addNumMsg ='Add Number' num1 : ''; num2 : ''; addNumber() { this.addNumEvent.emit(parseInt(this.num1) + parseInt(this.num2)); } }
import {NgModule} from '@angular/core'; import {BrowserModule} from '@angular/platform-browser'; import {ParentComponent} from './parent.component'; import {ChildOneComponent} from './childone.component'; import {ChildTwoComponent} from './childtwo.component'; @NgModule({ imports: [BrowserModule], declarations: [ParentComponent, ChildOneComponent, ChildTwoComponent], bootstrap: [ParentComponent] }) export class AppModule { }
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; import {AppModule} from './module'; const platform = platformBrowserDynamic(); platform.bootstrapModule(AppModule);
<html> <head> <title>Angular 2 Demo</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <script src="node_modules/core-js/client/shim.min.js"></script> <script src="node_modules/zone.js/dist/zone.js"></script> <script src="node_modules/reflect-metadata/Reflect.js"></script> <script src="node_modules/systemjs/dist/system.src.js"></script> <!-- Configure SystemJS --> <script src="systemjs.config.js"></script> <script> System.import('myApp').catch(function(err){ console.error(err); }); </script> </head> <body> <input-output>Please Wait...</input-output> </body> </html>
Run Application
Find the steps to run the example.1. Install Node.js and NPM in the system if not already installed. Make sure that Node.js version must be 4.x.x or higher and NPM version must be 3.x.x or higher.
2. Download the source code using download link given below in the example.
3. Go to the root folder of the project using command prompt and run npm install command.
4. Now run npm start command.
5. Now run index.html file. Find the print screen of the output.

References
ANGULAR 2 TEMPLATE SYNTAX:Input and output propertiesANGULAR 2 EventEmitter