DEV Community

Cover image for Understanding @Output and EventEmitter in Angular | iFour Technolab
Harshal Suthar
Harshal Suthar

Posted on • Originally published at ifourtechnolab.com

Understanding @Output and EventEmitter in Angular | iFour Technolab

What is @Output?

As we all know that you can archive two-way data binding with [(ngModel)], but what if we want to share data with one component to another component? To accomplish that we can use @Input and @Output.

Let's understand it with one example:

We are using a parent component and a child component.


<parent-component>
  <child-component></child-component>
</parent-component>

Enter fullscreen mode Exit fullscreen mode

Here parent-component is serving as a context for the child-component.By using the @Input and @Output child component can communicate with the parent component.

@Input: This will allow the parent component to update or share data in the childcomponent.

@Output: It allows child to share data with the parent component.

Let’s see how @Input works:

Image description Fig: Working of @Input

You will have to configure both parent-component and child-component to use@Input and @Output.

Child-Component

Step 1: We have to import input from angular/core

Step 2: Create a field in the export class which we will going to use from the parent component and use @Input decorator.

child.component.ts:

import {Component, Input} from '@angular/core'; // step 1
export class FruitDetailComponent {
@Input () fruit: string; // step 2
}

Enter fullscreen mode Exit fullscreen mode

As we can see @Input decorates fruit property, here we have set fruit type to string you can set it as per your requirement such as number, object, string, or Boolean. The value of fruit will be derived from its parent component

Step 3: lets add it in HTML page.

Child.component.html


  <xmp><p>
    this fruit name is: {{fruit}}</p>
   </xmp>

Enter fullscreen mode Exit fullscreen mode

Step 1: We will have to bind that property in the parent component. Use child component selector tag to bind that property. Use property binding"[ ]" to assign value to that variable.

Parent.component.html


  <app-child>
  </app-child>

Enter fullscreen mode Exit fullscreen mode

Step 2: Assign real value for currentFruit from app.component.ts file in Export class. Parent.component.ts


  export class AppComponent {
  currentFruit = 'Apple';
  }

Enter fullscreen mode Exit fullscreen mode

Read More: Building An Angular App With Azure Web Apps Service

So, here is what willgoing to happen: we have a value which we want to share with another component, so angular is going to pass 'currentFruit' from the parent. component to its child. a component using @Input.

Here is the image which might help you to understand.

Image description

How @Output Works?

It's a kind of reverse process of @input,@Output is used to share data from child component to parent component.

Image description Fig: Working of @Output

@output is a kind of doorway to pass data from the child component to its parent component.

@Output property will raise an event from the child component to notify the change to the parent component.@Output must have an EventEmitter to raise an event.EventEmitter is a class of @angular/core.

Now let's see how to use @Output.

Similarly like @Input, we will have to configure both, child and parent components.

For child.component:

Let's create an input property where the user can add value and a button that willraise an event on click.

Step 1: Import output and EventEmitter from angular/core in your ts file.

Step 2: Add a property with @Output decorator which has a type of EventEmitter.

Step 3:Create an add method in the same component ts file

So, your ts file will look like this:

Child.component.ts:


  import { Component } from '@angular/core';
  import { Output, EventEmitter } from '@angular/core'; //step 1
  @Component({
    selector: 'app-child',
    templateUrl: './child.component.html',
    styleUrls: ['./child.component.scss']
  })
  export class ChildComponent {
    @Output() newFruitEvent = new EventEmitter<string><app-child>();//step 2
    addNewFruit(value: string) {                //step 3
      this.newFruitEvent.emit(value);
    }
  }
  </app-child></string>  

Enter fullscreen mode Exit fullscreen mode

Step 4: Add input file with template variable ‘#newFruit’ and add a button with Event 'addNewFruit' to the component HTML page

child.component.html


  <label>Add a fruit: <input></label><button>Add to parent's 
    fruit list</button>

Enter fullscreen mode Exit fullscreen mode

The button click event is bounded to its component’s ts file with addNewFruit() method.

Now let's move to the parent component side:

Step 1: Create an array and a method that can push data in that array.

Parent.component.ts:


  export class AppComponent {
    fruits = ['Apple', 'Banana', 'Orange'];
    addFruits(newFruit: string) {
      this.fruits.push(newFruit);
    }
  }

Enter fullscreen mode Exit fullscreen mode

Step 2: In the parent template, we will have to bind that parent method to its child'sevent.

  <app-child><app-child>
  </app-child></app-child>

Enter fullscreen mode Exit fullscreen mode

The event binding, (newFruitEvent)=”addFruit($event)” will connect the event to its child component’s newFruitEvent, to the method in the parent ts file ‘addFruits()’.

This '$event' will have data which is entered by the user in the child component's input field, if we want to see the output of this code we can add the following code in our parent component HTML page.


  <xmp><ul><li> </li><li>{{fruit}}</li><li> </li></ul>
  </xmp>

Enter fullscreen mode Exit fullscreen mode

*ngFor will work like a loop and show all available fruit in fruits.

Using @Input and @Output together

We can use @Input and @Output for the same component with the following code:

Image description

The child selector app-child with ‘fruit’ and ‘deleteRequest’ being @input and @Output properties in the child component and the property 'currentfruit' and 'crossOffFruit()' are in the parent component.

Looking to hire dedicated Angular Developer? Your Search ends here.

EventEmitter

As we shown above, EventEmitter is used with @Output directive to emit custom events asynchronously and synchronously, and register handlers for those events by subscribing to an instance.

Let’s understand it with one example:


  import { Component } from '@angular/core';
  import { Output, EventEmitter } from '@angular/core'; //step 1
  @Component({
    selector : 'child',
    template : `<button>Notify my parent!</button>
    `
  })
  class Child {
    @Output() notifyParent: EventEmitter<any><app-child><app-child> = new EventEmitter();
    sendNotification() {
        this.notifyParent.emit('Some value to send to the parent');
    }
  }
  @Component({
    selector : 'parent',
    template : `
        <child></child>
    `
  })
  class Parent {
    getNotification(evt) {
        // Do something with (evt),which is sent by the child!
    }
  }
  </app-child></app-child></any>

Enter fullscreen mode Exit fullscreen mode

Here in this example, we have two-component and two classes with the name of Parent and child and we are performing some method in child and want to pass that data to its parent so in that case, we can utilize EventEmitter.

Conclusion

When you want to share data between two-component, you will have to use @Input and @Output with EventEmitter. We use EventEmitter to notify data changes from child component to parent component.

Image description

Top comments (0)