1

I know I can use {providedIn:'root'} to declare my service at the root of the app, also I can add it in a component level or module level by using providers:[].

My concern here is that I use lazy loaded module and the service doesn't get destroyed as the module is still loaded in cache? So is there an alternative to initializing and detroying the service outside of the constructor and ngOnDestroy method? so it get's destroyed when leaving the parent component?

perhaps using lazy loaded components that are standalone but I'm not sure?

JSmith
  • 4,519
  • 4
  • 29
  • 45
  • What problem are you trying to solve? Does this answer your question? https://stackoverflow.com/questions/50750193/angular-service-decorator-providedin-root-effect-on-lazy-loading?rq=2 – Brandon Taylor Mar 24 '23 at 13:56
  • @BrandonTaylor Thank you for your concern.This doesnot solve my problem.My problem is that for the moment I provide my service at a lazy loaded module level and it does not get destroyed when leaving the route.It is a well know behaviour but I cannot find a quality workaround to prevent this.Thanks in advance. – JSmith Mar 24 '23 at 14:18
  • I'm not sure you can prevent that, and unless it's causing some detrimental behavior in your app, I wouldn't worry about it. – Brandon Taylor Mar 24 '23 at 14:36
  • @BrandonTaylor I'ts defenitely causing problems.That's wy I'm asking :). – JSmith Mar 24 '23 at 14:41
  • What type of problems? – Brandon Taylor Mar 24 '23 at 14:46
  • @BrandonTaylor Well my problem is that I use a service to handle all media processes,First the service don' get destroyed which I assume cause memory leaks,secondly my media still gets played when leaving the route, thirdly intitializing and removing variables outside of normal workflow (constructor, ngOnDestroy) adds boilerplate code.Thanks in advance – JSmith Mar 24 '23 at 14:49
  • Interesting. I would assume any data provided by the service will get garbage collected at some point. I would have to dig into the code to help with the media still playing issue. – Brandon Taylor Mar 24 '23 at 14:54
  • @BrandonTaylor in short, I know how to solve the issue but the built-in behavior of angular force you to operate in a hacky way so I was just wondering if there were any workarounds.This behaviours don't appear in non-lazy-loaded modules but in the lazy loaded module it does.Thanks anyway. – JSmith Mar 24 '23 at 14:57

1 Answers1

2

There are two issues with that.

  1. Router does not immediately destroy some components, it can keep them alive. See RouteReuseStrategy for more information.
  2. Services from lazy modules are not unloaded.

You have at least two options:

  1. Do not use {providedIn:'root'}, provide service directly in top level component of your module (but be aware of issue #1), child components will be injected with service instance from parent component. It let's you implement OnDestroy hook in service. See https://angular.io/guide/hierarchical-dependency-injection#resolution-rules
  2. Implement your own cleanup strategy, e.g. subscribe to router event, or implement CanDeactivate guard and call cleanup method when user leaves your route.
kemsky
  • 14,727
  • 3
  • 32
  • 51
  • Thank you for your answer, unfortuately I won't approve it because of two reasons. 1: as long as the service is provided in a lazy loaded module event if I remove the `providedIn` property it won't call the `OnDestroy` hook. Secondly instead of using routes event I guess that using the `onDestroy` hook inside the parent component seems far easier to implement. Best, please tell me if you do not agree. – JSmith Mar 24 '23 at 16:49
  • Removing `providedIn` is not enough, you have to declare service in the `providers` of your component and then `ngOnDestroy` is called when component is destroyed (if it really does get destroyed). Using the `onDestroy` hook inside the parent component might be easier but you specifically asked for a different method :) – kemsky Mar 24 '23 at 17:20
  • yes I know I have to declare the service into `providers` but what I'm trying to tell you is that when a service is declared in a lazy loaded module the service never gets destroyed so the hook never gets called.Best... – JSmith Mar 24 '23 at 18:05
  • It indicates a bug in your code, component level services are destroyed , it does not matter if they are declared in a lazy module. – kemsky Mar 24 '23 at 18:35
  • Ho sorry if it wasn't explained well, the service is not at a component level, it is declared in module `providers[]`.I can't declare it at a component level because I would have 3 or 4 different different instances of the service which is what I don't want any ideas ( I have 1 parent component and 3 children that uses the same service ). – JSmith Mar 24 '23 at 18:43
  • You can declare service in parent, children will get the same instance. – kemsky Mar 24 '23 at 19:14
  • didn't know about that I'm going to test it thanks. – JSmith Mar 24 '23 at 19:19
  • It worked that's great.Maybe you can modify your answer and explain I can use component level services as the children will inheritate from it.Thanks that's awesome – JSmith Mar 24 '23 at 19:23