Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do you need to unsubscribe from @Output EventEmitter

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++;
  }
}
like image 459
Sebastian Patten Avatar asked Feb 13 '18 04:02

Sebastian Patten


People also ask

Should I use EventEmitter or subject?

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.

How does EventEmitter work angular?

๐ŸŽŠ 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.

How do you pass two parameters in EventEmitter?

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.

Is EventEmitter observable?

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.


1 Answers

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.

like image 133
yurzui Avatar answered Oct 17 '22 08:10

yurzui