3

HelloComponent gets a SampleService instance, defining a Service Provider. When HelloCompoment is destroyed, I don't understand why SampleService survives.

If HelloComponent got a SampleService instance by type (avoiding ServiceProvider), no problem occurs.


sample-service.ts

@Injectable()
export class SampleService implements OnDestroy{

 constructor(){
   console.log('created new sample service');
 }

 ngOnDestroy(){
  console.log('destroyed sample service');
 }
}

hello-component.ts

import { Component, OnInit, OnDestroy } from '@angular/core'
import { SampleService } from '../service/sample.service'

let ServiceFactory = () => {
  console.log('Providing new SampleService');
  return new SampleService();
};

let ServiceProvider = { 
    provide: SampleService,
    useFactory: ServiceFactory
  };

@Component({
  selector: 'hello',
  templateUrl: './hello.component.html',
  providers: [ServiceProvider]
})
export class HelloComponent implements OnInit, OnDestroy {

constructor(private sampleService: SampleService){}

ngOnInit(){
  console.log("Hello component created!")
}

ngOnDestroy(){
  console.log("Hello component destroyed!")
 }
}

Here stackblitz: https://stackblitz.com/edit/angular-vkhmma (click on toggleHello and see console logs)

How could I force the service destroying when component ends?

Fabio Formosa
  • 759
  • 5
  • 21

1 Answers1

2

This is a known issue in Angular, but one that is (unfortunately) by design.

The presence of an OnDestroy callback hook is checked at compile time and since your ServiceProvider is wrapping a Factory which creates a SampleService, the Angular compiler unfortunately has no idea that this hook even exists, so it will never be called.

Darren Ruane
  • 2,090
  • 1
  • 7
  • 16
  • Ok, all reported issues have been closed a year ago. I'm a little bit confused, I'm using latest stable ver (7.2.x). BTW, my service subscribes to some $subjects (rxjs) and it starts polling that never stops. any workaround? – Fabio Formosa Apr 08 '19 at 17:51
  • Yes because it is something that Angular have decided is **by design**. I presume they have no intentions of addressing it. I am not certain if there's any way around this I'm afraid, other than providing your service directly. You could also have your service only return an observable but **not** subscribe to it and then have the calling classes subscribe to that. – Darren Ruane Apr 08 '19 at 18:24