In the last article,We understood how to highlight selected row in Angular 2, Where we saw the concept of component communication and We had an overview ofinputs,outputs, and EventEmitter. In this article, We will be passing data between Angular 2 Components with the help of inputs,outputs, and EventEmitter.
By doing so, We will understand,
- How to use inputs and @input decorator.
- How to use outputsand @output decorator.
- What is EventEmitter and when to use it?
Setting up our Application
Let’s use Angular CLI to setup our application. If you don’t have Angular CLIinstalled on your machine run the below command to install it globally.npm install -g angular-cli
After Angular CLI intallation,to create a new Angular project Run below command. This command will create all the necessary files, download all the required external dependencies and do all of the setup work for us.
ng new AppName
The application
Here, we will pass data from one component to another component and vice versa. Just like the previous article, We will divide our application into components. The first component will be parent component and the second component will be child component.
To create components in the Angular application is very easy with the help of Angular CLI. Below command is used to create a component,ng generate component componentName
Run the below commands in order to achieve this,
- To create parentView component run :
ng generate component parentView
- To create childView component run :
ng generate component childView
We will pass data between these two components with the help of Inputs, Outputs,and Event Emitter.
Before going further let’s take a look at main.ts
and index.html
file where we have to use parentView component.
main.ts:
/* * Passing data Angular 2 Components * @author Shashank Tiwari */ import { bootstrap } from '@angular/platform-browser-dynamic'; import { enableProdMode } from '@angular/core'; import { environment } from './app/'; import { ParentViewComponent } from './app/parent-view/'; if (environment.production) { enableProdMode(); } bootstrap(ParentViewComponent);
index.html:
<!-- Passing data Angular 2 Components @author Shashank Tiwari --> <!doctype html> <html> <head> <meta charset="utf-8"> <title>Highlight selected Row in Angular 2</title> <base href="/"> <link rel="stylesheet" href="vendor/bootstrap/dist/css/bootstrap.min.css"> {{#unless environment.production}} <script src="/ember-cli-live-reload.js" type="text/javascript"></script> {{/unless}} <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/x-icon" href="favicon.ico"> </head> <body> <app-parent-view>Loading...</app-parent-view> {{#each scripts.polyfills}} <script src="{{.}}"></script> {{/each}} <script> System.import('system-config.js').then(function () { System.import('main'); }).catch(console.error.bind(console)); </script> </body> </html>
Passing data between Angular 2 Components
1. Sending data from ParentView into childView : inputs
Now we have included parentView component into our main.ts
file and we have used <app-parent-view>
the selector to render the parentView template.
From parentView component, we will send data to ChildView component.
To make this happen we will use Inputs and we will understand each and every aspect of it. Take a look at parent-view.component.ts
file what we have there.
parent-view.component.ts:
/* * Passing data Angular 2 Components * @author Shashank Tiwari */ import { Component,EventEmitter } from '@angular/core'; import { ChildViewComponent } from './../child-view/'; @Component({ moduleId: module.id, selector: 'app-parent-view', directives: [ChildViewComponent], templateUrl: 'parent-view.component.html', styleUrls: ['parent-view.component.css'] }) export class ParentViewComponent { sampleData : string ="some parent Data"; constructor(){} }
Nothing much to see here,exceptdirectives property inside the @component decorator to use childView component.
Let’s have a look at parent-view.component.html
, how we are sending data to childView component.
parent-view.component.html:
<!-- Passing data Angular 2 Components @author Shashank Tiwari --> <div class="container parent-view"> <div class=""> <h3>Parent Component</h3> <input type="text" class="form-control" value="{{ sampleData }}" [(ngModel)]='sampleData'> <hr> <div class="child-view"> <app-child-view [parentData]="sampleData" >app-child-view</app-child-view> </div> </div> </div>
As you can see the above code is comprehensible, except<app-child-view>
selector due to this [parentData]="sampleData"
term. What does [parentData]="sampleData"
do?
Let’s understand,
sampleData
is nothing but our data, that we want to send into childView component.parentData
inside squareBrackets ( [ ] ) acts as a key, by using this key we can receive the sampleData inside out childView component.
2. Receiving data into childView Component
Now let’s receive data into childView component using inputs. There are two ways to use inputs, either we can use @input decorator or we can use inputs attribute inside @component decorator.Here we will see both the method one by one.
1. Using @input decorator :
In order use, @input decorator we first need to include Input from @angular/core
library, as shown below.
import { Input } from '@angular/core';
Now let’s use @input decorator, to receive data from parent controller, In order to do that we will use the key written insidesquareBrackets ( [ ] ) in parent controller.
@Input('parentData') incomingData: string;
Above code does the exact same thing let’s break it down,
@Input('parentData')
: Here we are receiving theparentData
by using it as a key.incomingData
: We can refer this incoming input by name,Here we are referring this data by naming it to incomingData. If I talk in a more technical word, I would say here we making a difference between the instance property (incomingData)andattribute key ( i.e. parentData).:string
: Type of this incoming input.
2. inputs attribute inside @component decorator:
Here we need not to include Input from @angular/core
library, we can directly use inputs option inside @component decorator as shown below.Inputs attribute does the same thing.
After the explanation of @input decorator I think I need not explain the below code, let me know if you have any doubts.
@Component({ moduleId: module.id, ----- ----- inputs: ['parentData : incomingData'], ----- ----- })
Let’s see how we are receiving data into our childView component. In the below code we using @input decorator to receive data. Now we can use incomingData
variable anywhere in our childView component.
child-view.component.ts :
/* * Passing data Angular 2 Components * @author Shashank Tiwari */ import { Component,Input } from '@angular/core'; @Component({ moduleId: module.id, selector: 'app-child-view', templateUrl: 'child-view.component.html', styleUrls: ['child-view.component.css'], }) export class ChildViewComponent { @Input('parentData') incomingData: string; constructor() { } }
In child-view.component.html
, we can use incomingData
variable as shown below.
child-view.component.html :
<!-- Creating Highlight selected row Angular 2 application @author Shashank Tiwari --> <h3>Child Component</h3> <div class="parent-data"> Data from parebt view : <b>{{ incomingData }}</b> </div>
Sending data from childView to parentView : outputs
Here we will use outputs and EventEmitter, before digging into outputs let’s first understandEventEmitter.
EventEmitter:
EventEmitter is class which is used to emit custom events. In more simple term, EventEmitter is an object which create observer pattern. In the below image object A is event emitter class which emits custom events and other objects can receive the event emitted by object A.
EventEmitter Working
EventEmitter maintains the list of subcriber objects which can receive the event emitted by the EventEmitter object as explained above.
Outputs
With the help of EventEmitter, data is emitted from childView component and parentView component receives the emitted event. To practically implement this theory we will use outputs by attaching EventEmitter to it, here also we have two ways to use outputs .
Either we can use @output decorator or we can use outputs attribute inside @component decorator.
1. @output decorator:
Open child-view.component.ts
and add the below code. In the below code, we have to first import output and EventEmitter.
child-view.component.ts :
/* * Passing data Angular 2 Components * @author Shashank Tiwari */ import { Component,Input,EventEmitter,Output } from '@angular/core'; @Component({ moduleId: module.id, selector: 'app-child-view', templateUrl: 'child-view.component.html', styleUrls: ['child-view.component.css'], }) export class ChildViewComponent { @Input('parentData') incomingData: string; @Output('childData') outgoingData = new EventEmitter<string>(); childSampleData :string = "Some child Data"; constructor() { } public sendData(data:any){ this.outgoingData.emit(data); } }
Explanation:
1. In the ChildViewComponent class, we have output decorator with EventEmitter attached to it.
@Output('childData')
: Here childData acts as a key,which is used to carry the data in the form of Events.outgoingData
: This is an instance property or simply the name of the variable.= new EventEmitter()
: By doing this we are attaching EventEmitter to it childData or more accurately @output decorator.
2.sendData()
emits the data whenever this function executes.
2.outputs attribute inside @component decorator:
Using this technique we need not to import Output just like inputs. Let’s write child-view.component.ts
file with outputs attribute inside @component decorator.
child-view.component.ts:
/* * Passing data Angular 2 Components * @author Shashank Tiwari */ import { Component,Input,EventEmitter } from '@angular/core'; @Component({ moduleId: module.id, selector: 'app-child-view', templateUrl: 'child-view.component.html', styleUrls: ['child-view.component.css'], outputs: ['childData : outgoingData'], }) export class ChildViewComponent { outgoingData = new EventEmitter<string>(); childSampleData :string = "Some child Data"; constructor() { } public sendData(data:any){ this.outgoingData.emit(data); } }
Explanation:
1. In the @component decorator , we have outputs property outputs: ['childData : outgoingData']
which specifies the key value pair.
2. Here, childData
is acting as key and outgoingData
is acting as value.
And, rest of the things are same.
But wait when do we callsendData()
function ?
We call it from childView templates, whenever we intend to send data from childView component to parentView component.
In the below code, whenever any change occurs in ngModel
we callsendData()
function by using ngModelChange
.
child-view.component.html :
<!-- Creating Highlight selected row Angular 2 application @author Shashank Tiwari --> <h3>Child Component</h3> <div class="parent-data"> Data from parebt view : <b>{{ incomingData }}</b> </div> <div class="child-data"> <input type="text" class="form-control" value="{{ childSampleData }}" [(ngModel)]='childSampleData' (ngModelChange)="sendData($event)" placeholder="write some thing to send parent component"> </div>
Receiving event from childView into parentView
Lastly, we have to receive event emitted by childView component. Open the parent-view.component.html
add the below code.
parent-view.component.html :
<!-- Creating Highlight selected row Angular 2 application @author Shashank Tiwari --> <div class="container parent-view"> <div class=""> <h3>Parent Component</h3> <input type="text" class="form-control" value="{{ sampleData }}" [(ngModel)]='sampleData'> <br> <p>Data from child component : <b>{{ sampleChildData }}</b></p> <hr> <div class="child-view"> <app-child-view [parentData]="sampleData" (childData)='handleEvent($event)'>app-child-view</app-child-view> </div> </div> </div>
Notice that In the above code we have added (childData)='handleEvent($event)'
.
2. The (parenthesis) handle outputs : (childData)='handleEvent($event)'
Explanation:
childData
is the name of the output that we want from the childView component.handleEvent()
is a function that will be called whenever event will be emitted by childView component$event
a variable used to carry output data.
Now let’s check theparent-view.component.ts
file what we have there. In the below code, we have addedhandleEvent()
which updates the sampleChildData
variable.
parent-view.component.ts:
[snippet id=”194″]
Final thoughts
So which technique you should use to send and receive data, decorators orinput/output inside component decorator ?
Well, the answer is, it’s completely up to you and you can use any of them. decorators orinput/output inside component decoratorboth do the same thing.
For now, that’s it.
If you like this article share with others and for more Angular 2 article stay tuned.
Nice tutorial bhai >:)
Thanks bro.
Good explanation..Perfectly Working …
Thanks.
Thanks!
very nice, blog is very informative and simple,
Thank you.
could you have more angular practice projects if you have plz share with us and thanks for this its more useful for me.
First of all sorry for replying late. So, If you are completely new in Angular, then start with basic projects.
1. Create an Angular Todo application.
2. Play around with Angular Forms.
3. How data binding works.
4. learn about observables and all.
Then go to the next step.
1. Create and Todo application using Angular HTTP. (http://www.codershood.info/2016/10/23/angular-2-crud-application-using-nodejs/)
2. Build a Chat application.(http://www.codershood.info/2017/02/09/real-time-private-chatting-app-using-angular-2-nodejs-mongodb-socket-io-part-1/)
3. Create Customer Management app (https://github.com/DanWahlin/Angular-JumpStart)
After doing these project am sure you will feel enough confident to implement anything in angular. The thing is more you will do more you will learn. So keep implementing keep experimenting.
Hope this helps.