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 fired when service is provided using useFactory #14818

Closed
colinkahn opened this Issue Feb 28, 2017 · 4 comments

Comments

Projects
None yet
5 participants
@colinkahn

colinkahn commented Feb 28, 2017

I'm submitting a ... (check one with "x")

[ ] bug report => search github for a similar issue or PR before submitting
[x] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior
When you provide a service using useFactory, ngOnDestroy will never be called.

Expected behavior
Regardless of how you provide the service, ngOnDestroy should get called if it is a method on the service.

Minimal reproduction of the problem with instructions
https://plnkr.co/edit/aUaz6ewyM3m5JorsAoCO?p=preview

  1. Open the console.
  2. Click the "Create Component" button one or many times
  3. After a 2 second delay the component will be destroyed, but no console output will be seen.
  4. If you replace useFactory with useClass the problem goes away and you'll see output.

What is the motivation / use case for changing the behavior?
There are many cases, main motivator is that this isn't intuitive.

Please tell us about your environment:

  • Angular version: 2.4.8
  • Browser: Chrome 56.0.2924.87
  • Language: TypeScript 2.0

  • Node (for AoT issues): node --version =

@DzmitryShylovich

This comment has been minimized.

Show comment
Hide comment
@DzmitryShylovich

DzmitryShylovich Feb 28, 2017

Contributor

it's by design. there's no way to know if returned by the factory object has ngOnDestroy or not.

Contributor

DzmitryShylovich commented Feb 28, 2017

it's by design. there's no way to know if returned by the factory object has ngOnDestroy or not.

@colinkahn

This comment has been minimized.

Show comment
Hide comment
@colinkahn

colinkahn Feb 28, 2017

As a user useClass, useValue, and useFactory would seem to all just be different ways to achieve the same result. I think this should be a feature if it's not possible in the current implementation.

colinkahn commented Feb 28, 2017

As a user useClass, useValue, and useFactory would seem to all just be different ways to achieve the same result. I think this should be a feature if it's not possible in the current implementation.

@colinkahn

This comment has been minimized.

Show comment
Hide comment
@colinkahn

colinkahn Feb 28, 2017

A few other related examples showing that even useClass doesn't always work:

https://plnkr.co/edit/eIs7pjvldhcFrMmaJ4IV?p=preview

In that version I'm providing an abstract class and using useClass to specify a concrete version. ngOnDestroy is never called.

https://plnkr.co/edit/G7vLIvA1nz1dBoJ4sPcW?p=preview

Similar to the above, but using an OpaqueToken.

As far as I can tell the only time ngOnDestroy does work is if you use one of these (I believe they're equivalent):

[
  {
    provide: X,
    useClass: X,
  },
  // OR
  X,
]

colinkahn commented Feb 28, 2017

A few other related examples showing that even useClass doesn't always work:

https://plnkr.co/edit/eIs7pjvldhcFrMmaJ4IV?p=preview

In that version I'm providing an abstract class and using useClass to specify a concrete version. ngOnDestroy is never called.

https://plnkr.co/edit/G7vLIvA1nz1dBoJ4sPcW?p=preview

Similar to the above, but using an OpaqueToken.

As far as I can tell the only time ngOnDestroy does work is if you use one of these (I believe they're equivalent):

[
  {
    provide: X,
    useClass: X,
  },
  // OR
  X,
]

@ngbot ngbot bot added this to the Backlog milestone Jan 23, 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 #22466
Fixes #22240
Fixes #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 #22466
Fixes #22240
Fixes #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
@SonyStone

This comment has been minimized.

Show comment
Hide comment
@SonyStone

SonyStone Aug 25, 2018

I have simuler issue 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.

SonyStone commented Aug 25, 2018

I have simuler issue 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment