3d cartoon hands holding a phone

Unlock full course by purchasing a membership

Lesson 7

Handling Manual Subscriptions

For the times where you really do need to subscribe

STANDARD

Handling Manual Subscriptions

As we discussed in the last lesson, sometimes it isn’t feasible for us to use the async pipe to handle subscribing/unsubscribing to a stream for us. This might be true when the “destination” for your data isn’t actually the template. Maybe you want to send a POST request to send data to a server, and don’t need to display anything about that request in the template - in this case using the async pipe probably doesn’t make sense.

Another situation that comes up a lot for people is reacting to the valueChanges stream with ReactiveForms. We have talked about this observable stream before - valueChanges will emit every time the user modifies the value of the associated form control. An example of why you might need to subscribe manually in a situation like this is:

ngOnInit(){
    this.myForm
        .get('fieldOne')
        .valueChanges.pipe(
            switchMap((val) => this.exampleService.getRelatedVal(val))
        )
        .subscribe((result) => {
            this.myForm.get('fieldTwo').setValue(result)
        })
}

What is happening here is that when fieldOne changes, we want to take that value and make a call to a service to retrieve some related value. We then want to set that onto a different field in the form. You could consider some kind of auto-complete situation, filling in a value in one field might cause others to be filled based on that value.

In this case, we can’t really use the async pipe, so a subscribe here probably makes the most sense. But… if we subscribe then we should also make sure we unsubscribe at some point. How exactly should we do that?

How to Unsubscribe Manually

If you do subscribe manually at some point, it is important to understand how to unsubscribe safely. If you ever write .subscribe() in your code you should always make sure you unsubscribe from that stream at some point. Technically, there are situations where you don’t have to unsubscribe - certain types of observables might just emit one value and then complete. If the complete() notifier has been called, then the stream is already unsubscribed so there would be no need to do it manually.

This is a dangerous game to play, even in situations where it seems like it might be safe to not bother with unsubscribing there might be tricky little gotchas you aren’t considering. Rather than trying to reason about when you need to unsubscribe and when you don’t, it is much safer to always apply the general rule of: always unsubscribe.

The following are a few common techniques that you can use to handle this.

Store a reference to the subscription

This is the sort of “obvious” way to unsubscribe but I generally wouldn’t recommend doing this as other ways are generally more efficient. Still, I think it is important to cover since it sort of the default way to go about it.

export class HomeComponent implements OnInit, OnDestroy {

    emitOnceASecondSubscription: Subscription;

    ngOnInit(){
        const emitOnceASecond$ = interval(1000);
        this.emitOnceASecondSubscription = emitOnceASecond$.subscribe((val) => console.log(val));
    }

    ngOnDestroy(){
        this.emitOnceASecondSubscription.unsubscribe();
    }
}
STANDARD
Key

Thanks for checking out the preview of this lesson!

You do not have the appropriate membership to view the full lesson. If you would like full access to this module you can view membership options (or log in if you are already have an appropriate membership).