Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 - Does subscribing to FormControl's valueChanges need an unsubscribe?

Tags:

angular

rxjs

Below is a simple example of what I am asking about:

class AppComponent {    someInput: FormControl = new FormControl('');   private subscription: Subscription;    constructor(){      this.subscription = this.someInput.valueChanges         .subscribe(() => console.log("testing"));   } } 

I have 2 questions:

1) Do I have to eventually unsubscribe from this? 2) Most importantly, whatever the answer is to #1, WHY is that the answer?

Any insight would be appreciated!

Thanks!

like image 882
user1902183 Avatar asked Dec 28 '16 14:12

user1902183


People also ask

Do we need to unsubscribe subject in Angular?

🎩 Automagically Unsubscribe in Angular As you probably know when you subscribe to an observable or event in JavaScript, you usually need to unsubscribe at a certain point to release memory in the system. Otherwise, you will have a memory leak. A memory leak occurs when a section of memory that is no longer being…

Do I need to unsubscribe from Observable in service?

You don't need to unsubscribe from observable created by Http or HttpClient because it is finite observable (value will be emitted only once and complete will be called). However, you CAN unsubscribe from the observable created by HttpClient to cancel the request.

Does Observable complete unsubscribe?

In these cases, the observable will call . complete() after it has emitted all of it's values. There's no need to unsubscribe. It completes on it's own, which means it unsubscribes all subscribers automatically.


1 Answers

UPDATE OCT 2020

This question gets a lot of SEO traffic and whilst my answer is still technically correct, I strongly advise you to read this.


  1. Yes, you do. Note that you do not need to unsubscribe from http calls because they auto-complete themselves.

  2. You must unsubscribe to prevent memory leaks and to avoid unexpected side-effects in your application.

For example, when a component is destroyed, the subscription will remain if you don't unsubscribe from it. The next time the user navigates back to that page and the component gets loaded again, it will create another subscription to valueChanges - now you have 2 active subscriptions processing data simultaneously and that will lead to unexpected behavior in your app.

There is a relatively easy way to setup auto-unsubscribing.

The RxJS way is to use takeUntil - it basically lets you set up a subscriber which keeps listening UNTIL you tell it not to :)

First we need a destroy subject in our component:

  private destroy$ = new Subject(); 

Then tell it to emit a value when our component is destroyed:

  ngOnDestroy(){     this.destroy$.next();     this.destroy$.complete();    } 

Now setup your subscribes to use it:

this.someInput.valueChanges   .debounceTime(1000)   .distinctUntilChanged()   .takeUntil(this.destroy$)   .subscribe (newValue => { 

All the subscribes setup like this will then auto-unsubscribe when they receive the destroy notification.

This is especially useful if, for example, you have an ngFor that is dynamically adding controls, and each control added has an valueChanges subscription (eg. an array of controls). In such a scenario you don't need to loop through the array in ngOnDestroy and unsubscribe one-by-one. Just use takeUntil :)

I recommend reading Ben Lesh's article (RxJS lead engineer at Google) for a great overview of takeUntil, including pros/cons.

like image 134
rmcsharry Avatar answered Oct 05 '22 23:10

rmcsharry