Search code examples
angulartypescriptrxjsbehaviorsubjectunsubscribe

Angular: Confused over communicating between unrelated components without a memory leak


From what I've read, the preferred way for unrelated Angular components to communicate is to create a service and use an RxJS BehaviorSubject. Here is one of the many online references to this approach that I found:

https://fireship.io/lessons/sharing-data-between-angular-components-four-methods/

For unrelated components, this site, like others, advocates doing something similar to the following in the service:

private messageSource = new BehaviorSubject('default message');
currentMessage = this.messageSource.asObservable();

changeMessage(message: string) {
     this.messageSource.next(message)
}

Then, in the other component:

ngOnInit() {
     this.data.currentMessage.subscribe(message => this.message = message)
}

This way is pretty straightforward and I was able to share data using this approach. However, in every reference I've read about subscribing they all say it's important to unsubscribe to avoid a memory leak. There seems to be no way to unsubscribe using this approach. Is there something I'm misunderstanding or some additional step(s) required to avoid a memory leak when using this approach? Is there some approach that I should use instead?


Solution

  • You can unsubscribe easily in your component ngOnDestroy method:

    OtherComponent implements OnInit, OnDestroy {
    
      private subscription: Subscription;
    
      //...
    
      ngOnInit() {
        this.subscription = this.data.currentMessage.subscribe(
          message => this.message = message
        );
      }
    
      ngOnDestroy() {
        this.subscription.unsubscribe();
      }
    }
    

    Alternative you can do something fancy with RxJs takeWhile and a subject that you emit with a value on destroy.

    You find that solution and other great examples here in this blog post on Medium.