#Can a service provided in root with a shareReplayed observable cause memory leaks?

7 messages · Page 1 of 1 (latest)

woeful shale
#

I have this service that's provided in root in an Angular 14 application:

@Injectable({
  providedIn: 'root',
})
export class CoreThingService {
  public readonly allThings$: Observable<Thing[]> =
    this.fetchThings().pipe(take(1), shareReplay(1));

  fetchThings(): Observable<Thing[]> {
     // fetch things
  }
}

Does allThings$ need to be unsubscribed somewhere in the CoreThingService to prevent memory leaks, even if it's provided in root instead of in a feature module?

If it does, how can I use something like Chrome DevTools to demonstrate the difference in memory use?

long egret
#

You can't possibly unsubscribe without subscribing first. What should unsubscribe is the thing that subscribes, not the service which just provides the observable. And in this case, even if the thing that subscribes doesn't unsubscribe, you wouldn't have a memory leak since the observable completes immediately.

oblique cosmos
#

yup thats what I want to say

woeful shale
autumn heart
#

I don't know what you are trying to do, but i think the take(1) is a mistake here

and as @long egret is trying to say, you need to take care of the last obs in the chain.

allThings$ = of(xxx) <== nothing to do

a$ = allThings.pipe(to things)
b$ = allThings.pipe(to things)

a$.subcribe() <== need to unsuscribe
b$.subcribe() <== need to unsuscribe

shareReplay is just an operator to avoid retriggering your allthing observable. allThing will save the last emitted value and give that value to any obs that listen to it without replaying the entire thing

I hope you get it? 😇

woeful shale
#

@autumn heart fetchThings() makes an api call and returns a large http response, so the purpose of allThings$ is to make that data available to any service/component in the app that needs it, without calling the api endpoint multiple times. It's data that's large in size, but rarely changes.

So in your code example, even though allThings$ completed on its own, a$ and b$ would still need to be unsubscribed (assuming their pipes don't involve other long-running observables)?

long egret
#

The best practice is to always unsubscribe. Now if you have the guarantee that the observable completes immeciately, or almost immediately, and that this will never change, not unsubscribing is not the end of the world, and won't cause a memory leak.
If you program declaratively, and end up using the async pipe in the view to access the values emitted by the observable, then unsubscription on component destruction is automatic.