37

Is it possible to have life-cycle hooks for a service that is annotated with @Injectable()?

I'd have expected the life-cycle hooks to be called on a service like this, but I was proven wrong, it seems to be working on @Component only. Is there a way to get informed in a service when dependency injection creates / destroys a service?

import {Component, Injectable, OnInit, OnDestroy} from 'angular2/core';

@Injectable()
export class SampleService implements OnInit, OnDestroy {
    ngOnInit() {
        console.log("OnInit")
    }
    ngOnDestroy() {
        console.log("OnDestroy")
    }
}

@Component({
  selector: "sample",
  template: "<div>Sample Component</div>",
  providers: [ SampleService ]
})
export class SampleComponent {
  constructor() { private _sampleService: SampleService }
}
Martin C.
  • 12,140
  • 7
  • 40
  • 52
  • 4
    This isn't a duplicate of the other question because it also mentions OnDestroy whereas the other question only mentions OnInit. The documentation for OnDestroy actually states that services should support it. I was also proven wrong. – Patrick Graham Mar 01 '17 at 14:55
  • In your case, I think its the approach you're taking might be the wrong way around. Injectables/Services are simply tools to get data and such. If you want a life-cycle hook to have the service do something on start, I would suggest putting the `ngOnInit` hook on your main app Component, that would make a call to the injected service to kick it off. Basically use the main app component to kick off the service, which will keep you parts as they are. It's all about perspective. ;) – Guy Park Feb 06 '19 at 01:09
  • @GuyPark: That's basically what I do as a workaround. I had hoped for the life-cycle of the service to be more automatic, but I understand the problems involved, so yes, that's a valid solution. – Martin C. Feb 06 '19 at 07:25

2 Answers2

33

Injectables are just normal classes (normal objects) and as such, they have no special lifecycle.

When an object of your class is created, the class’s constructor is called, so that’s what your “OnInit” would be. As for the destruction, a service does not really get destroyed. The only thing that might happen is that it gets garbage collected once there is no longer a reference to it, which likely happens after the dependency injector is removed itself. But you generally have no control over it, and there is no concept of a deconstructor in JavaScript.

@Injectable()
export class SampleService {
    constructor() {
        console.log('Sample service is created');
    }
}
poke
  • 369,085
  • 72
  • 557
  • 602
  • `constructor()` would have been my guess, and I also know that objects get garbage-collected. Since the life-cycle of a DI-managed object is more or less defined via the scope of the Component that `provide`s it, I had hoped that there would be life-cycle methods even for those objects. – Martin C. Mar 23 '16 at 21:43
  • No, specifying `providers` for a component only tells the DI framework to use a new injector there; it does not mean anything about *how* or *when* the actual object is created. You could for example use a custom `provide()` call to inject a singleton object which is only created once but provided separately (with individual injectors) to multiple components that have their own lifecycle. – poke Mar 23 '16 at 21:46
  • 9
    [ngOnDestroy](https://angular.io/api/core/OnDestroy) is called when a service is destroyed. – Alex Vauch Jun 21 '17 at 15:14
  • 3
    @AlexVauch That will tell you *when* the service is destroyed, but it does not give you control about actually destroying the service. – poke Jun 21 '17 at 16:21
  • 1
    @poke, That's exactly what a HOOK is: A function being called from somewhere else. And in this case it's automatically called when the provider of the service is destroyed. – Fredrik_Borgstrom Feb 01 '19 at 10:55
10

The ngOn* lifecycle hooks you show are only for components. You could inject another service (call it TrackServiceLifecycles) into SampleService and have SampleService's constructor() call a method on the other service to inform it that it was created. But I can't think of a way to notify the other service when SampleService is destroyed (garbage collected).

See also ECMAScript 6 class destructor

Community
  • 1
  • 1
Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492