On the Angular website they have an example of a Parent and Child component talking to each other using @Output() onVoted = new EventEmitter<boolean>();
. See below.
In this given example, do you need to unsubscribe from the EventEmitter to prevent memory leaks/bloat? Or does the Framework take care of that for you?
component-interaction/src/app/voter.component.ts
import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
selector: 'app-voter',
template: `
<h4>{{name}}</h4>
<button (click)="vote(true)" [disabled]="voted">Agree</button>
<button (click)="vote(false)" [disabled]="voted">Disagree</button>
`
})
export class VoterComponent {
@Input() name: string;
@Output() onVoted = new EventEmitter<boolean>();
voted = false;
vote(agreed: boolean) {
this.onVoted.emit(agreed);
this.voted = true;
}
}
component-interaction/src/app/votetaker.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-vote-taker',
template: `
<h2>Should mankind colonize the Universe?</h2>
<h3>Agree: {{agreed}}, Disagree: {{disagreed}}</h3>
<app-voter *ngFor="let voter of voters"
[name]="voter"
(onVoted)="onVoted($event)">
</app-voter>
`
})
export class VoteTakerComponent {
agreed = 0;
disagreed = 0;
voters = ['Mr. IQ', 'Ms. Universe', 'Bombasto'];
onVoted(agreed: boolean) {
agreed ? this.agreed++ : this.disagreed++;
}
}
EventEmitter and Subjects serve the same purpose - to notify about an event to an observer. But EventEmitter should only be used to notify an event from the child to the parent i.e., it should only be used with @Output() . To notify about an event across different components, Subjects should be preferred.
๐ Event Emitters in Angular ๐Data flows into your component via property bindings and flows out of your component through event bindings. If you want your component to notify his parent about something you can use the Output decorator with EventEmitter to create a custom event.
For passing the parameters, we will wrap all the parameters inside the curly brackets (this will combine them as a single object) and pass it to the emit method. To receive the parameters in the parent component, we will make a similar type of object and update its value with that of the received object.
EventEmitter is used in the directives and components to emit custom events either synchronously or asynchronously. Since EventEmitter class extends RxJS subject class, this means it is observable and can be multicasted to many observers.
If you see example on the Angular website and they don't unsubscribe then why do you think you should do it?
Angular takes care about it.
When it creates directive instance it subscribes to the outputs:
if (def.outputs.length) {
for (let i = 0; i < def.outputs.length; i++) {
const output = def.outputs[i];
const subscription = instance[output.propName !].subscribe(
eventHandlerClosure(view, def.parent !.nodeIndex, output.eventName));
view.disposables ![def.outputIndex + i] = subscription.unsubscribe.bind(subscription);
https://github.com/angular/angular/blob/235a235fab45b2c82f8758fc9c0779f62a5b6c04/packages/core/src/view/provider.ts#L138-L140
and when it destroyes component it also automatically unsubscribes from output subscriptions:
export function destroyView(view: ViewData) {
...
if (view.disposables) {
for (let i = 0; i < view.disposables.length; i++) {
view.disposables[i]();
So every time you destroy your directive angular will dispose all subscription for you.
But if you subscribe to EventEmitter
manually in code then you have to unsubscribe yourself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With