Home  >  Angular 2

Angular 2 @Input and @Output Example

By Arvind Rai, 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.

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;  
Now find array data type with @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>  
Now find @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>(); 
In the above code snippet addStudentEvent will become custom event name. Now find @Output decorator without aliasing.
@Output() 
sendMsgEvent = new EventEmitter<string>();	 
Here 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> 
Here we are doing property binding. 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;	 
What we achieve that 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>  
Here 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>();	 
What we achieve here is that 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');  
2. Create a custom element in parent component that is a selector of one of our child component. Here we will perform component property binding.
<child-two [stdLeader] = "stdLeaderObj"> </child-two>  
3. Use @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;	 
4. Now we are ready to fetch values from input component property in our child component.
{{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>	 
2. Find the method created in child component that will be fired when 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));
}	 
3. In the child component, create an instance of 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>();  
4. Now we are performing custom event binding. The custom event 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>  
5. The event 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 the above code we will observe that we are using question mark ? 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;
        }			
}  
childone.component.ts
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);
        }		
} 
childtwo.component.ts
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));
        }		
}   
module.ts
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 { } 
main.ts
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {AppModule} from './module';
const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);  
index.html
<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.
Angular 2 @Input and @Output Example

References

ANGULAR 2 TEMPLATE SYNTAX:Input and output properties
ANGULAR 2 EventEmitter

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI
FIND MORE TUTORILAS










Copyright ©2017 concretepage.com, all rights reserved |Privacy Policy | Contact Us