When a service got destroyed in angular
Tags: typescript, angular, javascript
Published: 2019-08-30 14:18:27

*Cover Photo by Asa Rodger on Unsplash*

If we read the OnDestroy lifecycle hook api description [Angular OnDestroy](https://angular.io/api/core/OnDestroy) we can use it on services.
But more than this information, we cannot find on it. If we look on the lifecycle hook page. Nothing is explained there, so time to try a few things out.

## How we use services?
First we will dig into the usage of services. Services can be provided on different ways to the applications:

### On root level
The service is available for everyone, every module can use this root service. It is provided as a singleton, so it lives only ones, and every action on this service, every observable is shared through the whole application.

How can define it on 2 ways. With the providedIn, then you don't provide it in your module
```typescript 
@Injectable({ providedIn: 'root'})
export class RootService { ... }
```

sidenote on providedIn:
> You can also use `provideIn: module`, but this is still in experimental phase, so be carefull, `providedIn: 'root'` is good integrated

Or Inject it on the root module
```typescript 
@Injectable()
export class RootService { ... }

@NgModule({
	providers: [ RootService ],
})
export class AppModule{}
```

### On module level
We can also create our services on module level, these services are private and dedicated to that specific module. There logic is shared just inside that module
```typescript 
@Injectable()
export class ModuleService { ... }

@NgModule({
	providers: [ ModuleService ],
})
export class MyCustomModule{}
```

### On component level
These services are injected at component level, so they are only living once the component is alive
```typescript
// providedIn
@Injectable()
export class Componentervice { ... }

@Component({
	selector: 'my-component',
  template: '...',
	providers: [ Componentervice ],
})
export class MyComponent{}
```

## The lifecycle of a service.
First we are interested when a service is created. We can add a simple test for it. Just  create some code like below:
```typescript
export class MyService {
	constructor(){
		console.log('constructor initialized')
  }
}
```

To test this logic we have a few testcases, create services on 
- Root level
- Module level
- Lazy loaded module
- Component level

### Initialise the service
> All service are initialised on the first usage.  

A side-note on services. It is not enough to provide it, we should actual perform an action on that service to be initialised, so adding it to a providers array, is not a way of  initialising that service. We can have a fist usage of the service on different ways, like use it through a component or a factory, ….

So knowing that, the services are all initialised on the first usage, that is one thing that we are sure about.
That means also, that lazy loaded services are only initialised the first time a route is loaded, an providedIn: ‘root’ service is only initialised the first time it will be used, …. .


Let’s look at the outputs, here we see an interesting pattern. As expected the root, module and lazy service providers are only once created. When we recreate the component, it the service is not created again
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/tlw90o8u1ixdcanhtl3b.png)
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/yhh36r9nho1013gekknk.png)
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/4cwn4r0qy9wxz0w3trfg.png)

But the most interesting part is the component provided service: Each time the component is created, the service is also created
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/r9fm1gk48id7wv8m1i8l.png)

> Only component providers are created each time a component is created  

### Destroy the service
Now we do the same thing but we destroy the service with the ngOnDestroy hook.
For some reasons we thick the preserve log checkbox in google, so we can track the history of our logging even when we leave the page.
 
Again the testing code will be similar for each service
```typescript
@Injectable()
export class MyService implements OnDestroy {
  name = 'xxx service';
 
  constructor(private counterService: CounterService) { 
    console.log('Construct the xxx service')
  }  

  ngOnDestroy() {   
    console.log('Destroy the xxx service')
  }
}
```

First we look at the component service, as we have the component service each time created, we expect that it destroys when the component get destroys. 
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/nfj09yu73xntbwdannki.png)

If we look at the 3 other services, then we see that these are never destroyed. Even not when we leave the page. You can get it by accident when you leave the page, but you are not ensured about this.
 ![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/oh41n3t43xunwzrm1q22.png)

So the conclusion on this ngOnDestroy hook:

## Conclusion
- You are never sure that a service is destroyed, expect if you provide it on component level
- If you provide a service on component level and you refactor your code, then you need to pay attention on this 

> Be careful when you use this hook on services   

Complete tryout is available on stackblitz:
{% stackblitz service-lifecycle view=preview %}