New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ngOnDestroy not called for injectables created via factory providers #22466

Closed
IgorMinar opened this Issue Feb 27, 2018 · 5 comments

Comments

@IgorMinar
Member

IgorMinar commented Feb 27, 2018

Current behavior

export class DestroyTest implements OnDestroy {
  ngOnDestroy() {  // <<<<< this method is NEVER called
    console.log('ngOnDestroy DestroyTest called');
  }
}

export class DestroyTest2 implements OnDestroy {
  ngOnDestroy() { // <<<<< this method IS called when the app ref is being destroyed
    console.log('ngOnDestroy DestroyTest2 called');
  }
}

export function createDestroyTest() {
  return new DestroyTest();
}

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, HelloComponent ],
  bootstrap:    [ AppComponent ],
  providers: [
    {provide: DestroyTest, useFactory: createDestroyTest},
    DestroyTest2
  ]
})
export class AppModule {
  constructor(
    destroyTest1: DestroyTest, destroyTest2: DestroyTest2) {}
}

Expected behavior

the ngOnDestroy method, if present, should be called on all values provided via DI regardless of the provider type.

Minimal reproduction of the problem with instructions

https://stackblitz.com/edit/angular-h15slp

Environment


Angular version: 6.0.0-beta.x

// Note: reported by GX

@trotyl

This comment has been minimized.

Contributor

trotyl commented Feb 27, 2018

Duplicate of #14818, #22240

@tmair

This comment has been minimized.

tmair commented Mar 1, 2018

There are already bugs within the angular framework, that are caused by this issue (for example the Router is created via a factory function).

The associated bugs contain some comments, that it is currently not possible to do an analysis at compile time if the factory function returns an object that implements the ngOnDestroy hook and that currently this works as intended.

@ngbot ngbot bot modified the milestones: needsTriage, Backlog Mar 2, 2018

@swicken

This comment has been minimized.

swicken commented Mar 22, 2018

We are encountering what appears to be this issue in our application as well. Any route changes with routerLink or router.navigate, ngOnDestroy is not called and the component becomes detached in memory. This is causing a pretty severe memory leak.

Does anyone have any workarounds for this?

@alxhub alxhub self-assigned this Mar 22, 2018

alxhub added a commit to alxhub/angular that referenced this issue May 7, 2018

fix(core): call ngOnDestroy on all services that have it
Previously, ngOnDestroy was only called on services which were statically
determined to have ngOnDestroy methods. In some cases, such as with services
instantiated via factory functions, it's not statically known that the service
has an ngOnDestroy method.

This commit changes the runtime to look for ngOnDestroy when instantiating
all DI tokens, and to call the method if it's present.

Fixes angular#22466

alxhub added a commit to alxhub/angular that referenced this issue May 7, 2018

fix(core): call ngOnDestroy on all services that have it
Previously, ngOnDestroy was only called on services which were statically
determined to have ngOnDestroy methods. In some cases, such as with services
instantiated via factory functions, it's not statically known that the service
has an ngOnDestroy method.

This commit changes the runtime to look for ngOnDestroy when instantiating
all DI tokens, and to call the method if it's present.

Fixes angular#22466

alxhub added a commit to alxhub/angular that referenced this issue May 7, 2018

fix(core): call ngOnDestroy on all services that have it
Previously, ngOnDestroy was only called on services which were statically
determined to have ngOnDestroy methods. In some cases, such as with services
instantiated via factory functions, it's not statically known that the service
has an ngOnDestroy method.

This commit changes the runtime to look for ngOnDestroy when instantiating
all DI tokens, and to call the method if it's present.

Fixes angular#22466

alxhub added a commit to alxhub/angular that referenced this issue May 7, 2018

fix(core): call ngOnDestroy on all services that have it
Previously, ngOnDestroy was only called on services which were statically
determined to have ngOnDestroy methods. In some cases, such as with services
instantiated via factory functions, it's not statically known that the service
has an ngOnDestroy method.

This commit changes the runtime to look for ngOnDestroy when instantiating
all DI tokens, and to call the method if it's present.

Fixes angular#22466
Fixes angular#22240
Fixes angular#14818

alxhub added a commit to alxhub/angular that referenced this issue May 7, 2018

fix(core): call ngOnDestroy on all services that have it
Previously, ngOnDestroy was only called on services which were statically
determined to have ngOnDestroy methods. In some cases, such as with services
instantiated via factory functions, it's not statically known that the service
has an ngOnDestroy method.

This commit changes the runtime to look for ngOnDestroy when instantiating
all DI tokens, and to call the method if it's present.

Fixes angular#22466
Fixes angular#22240
Fixes angular#14818

@IgorMinar IgorMinar closed this in fc03427 May 8, 2018

IgorMinar added a commit that referenced this issue May 8, 2018

fix(core): call ngOnDestroy on all services that have it (#23755)
Previously, ngOnDestroy was only called on services which were statically
determined to have ngOnDestroy methods. In some cases, such as with services
instantiated via factory functions, it's not statically known that the service
has an ngOnDestroy method.

This commit changes the runtime to look for ngOnDestroy when instantiating
all DI tokens, and to call the method if it's present.

Fixes #22466
Fixes #22240
Fixes #14818

PR Close #23755
@amitport

This comment has been minimized.

Contributor

amitport commented Jul 4, 2018

@IgorMinar @alxhub this is not resolved for me after fc03427
(using angular 6.1.0-beta.3)

@SonyStone

This comment has been minimized.

SonyStone commented Aug 25, 2018

I have same problem with Factory providers from this gide:

https://angular.io/guide/dependency-injection#factory-providers

Minimal reproduction of the problem with instructions
https://stackblitz.com/edit/angular-service-factory-issue?file=src%2Fapp%2Ftest.service.ts

Click the "toggle" button one or many times
Test 1 Service will be created and destroyed. Test 2 Service will be created and never destroyed.

Environment
Angular version: 6.1.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment