Stop Unsubscribing in Angular


When you start playing with observables, you need to unsubscribe from them otherwise bad things will happen to your program. You’ll often see code where we subscribe at the component level and then unsubsribe ngOnDestroy. This works, but you can reduce the amount of logic in your component with one easy trick.

Here is a nice component called NameComponent. Notice that handleNameChange triggers our nameEmitter to emit a name from a form. But it does not subscribe anywhere in the component.

export class NameComponent implements OnInit {
  @Output() nameEmitter: EventEmitter<string> = new EventEmitter();
  public nameForm: FormGroup = this.fb.group({
    name: [{value: '', disabled: false}, Validators.required],
  });
  public handleNameChange: Observable<void> = this.passcodeForm.valueChanges.pipe(
    tap(() => this.nameEmitter.emit(this.nameForm.value.name)),
    switchMap(() => EMPTY)
  );
  constructor(private fb: FormBuilder) {}

...

}

So how does handleNameChange actually have our nameEmitter emit when there is no subscription? Let’s take a look at the template You’ll see that we can set up our subscription in the template with the async pipe. Here are the docs for it

{{handleValueChange | async}}
<form [formGroup]="nameForm">
  <mat-form-field>
    <input matInput formControlName="name" placeholder="Enter Name" />
  </mat-form-field>
</form>

The async pipe magically subscribes to our observable and unsubscribes from it when the component is destroyed. You can see this in the source code for the pipe if you’re curious. The great part is that we used tap as a side effect to talk to other parts of our component!

  ...
    tap(() => this.nameEmitter.emit(this.nameForm.value.name)),
  ...