5
votes

I have a high level questions about subscription handling in Angular2. I've read a lot recently about how poor subscription handling can lead to memory leaks in your code due to not properly unsubscribing.

An easy solution for @Components is to meet all the subscriptions around and handling them in ngOnDestroy lifecycle event.

However, for controllers that are not part of @Component and do have subscriptions, what's the best approach to properly unsubscribing? Currently, I am thinking of having the controller expose either the subscriptions, or its own onDestroy method, but this doesn't feels like it can be done easily/generically so I'd love to hear other options/opinions.

Thanks!

Edit: clarifying that this is not a service issue, but just a controller issue.

1
Services will rarely be destroyed due to them being singletons by default.Harry Ninh
Like Harry said, services ideally are not destroyed and are long lived. In typical scenarios one would have the services return the observables and let the components subscribe to them. Not often have I had the need to subscribe in services and if that did happen and had to clean up I did manually.Thibs
I should be more clear. Service isn't the word I was looking for but controller is (following the MVC architecture). In my case, I render lots of Component that have a controller associated to them to dictate now UI related logic. In these controllers I am having the problem have correctly dealing with subscriptions in a clean manner. Hope that clarifies things, if not, please let me know where I can elaborate more.cjr

1 Answers

0
votes

Try to avoid manual subscriptions

  1. Don't use subscriptions on angular-bound streams when you are outside the an angular-context, this will just lead you messy situations.
  2. Try to avoid manual subscriptions at all. Especially in components! Manual subscriptions are not neccessary in 90% of the cases.

Why? And how should I do it then?

In most cases your application only needs data to flow for the information that is currently displayed on the screen -> let the template handle the subscription by using the async-pipe - no manual subscription required in any controller, this can all be achieved by concatinating and extending multiple rxjs-streams without having any manual subscription.

You can still have utility-classes outside the angular-contexts that perform some data-calculations and other logic, however embed those methods inside the streams or have them extend an existing stream, but don't do any manual subscriptions there.

What about perpetual calculations that have to be executed regardless of the data being displayed?

It is argueable if this case really exists, but let's say it does: This is a typical case for a service -> having subscriptions in services is okay, since services are singletons and therefor are not a huge risk of a memory-leak.