Angular Lifecycle Hooks
Tags: angular
Published: 2022-12-09 07:10:14

---
title: Angular Lifecycle Hooks
published: true
date: 2022-07-22 00:00:00 UTC
tags: angular
canonical_url: https://www.prestonlamb.com/blog/angular-lifecycle-hooks
---

## tldr;

Each Angular component has a lifecycle that lasts from the time the component is added to the page until it is removed from the page. There are several times to hook into the lifecycle, where you can run some code necessary for the component. We’ll look at a few of the most common hooks.

## Angular Lifecycle Hooks

Angular has several lifecycle hooks, which you can [view in detail on the docs](https://angular.io/guide/lifecycle-hooks). Here’s the list of hooks:

- `ngOnChanges`
- `ngOnInit`
- `ngDoCheck`
- `ngAfterContentInit`
- `ngAfterContentChecked`
- `ngAfterViewInit`
- `ngAfterViewChecked`
- `ngOnDestroy`

Each of the above lifecycle hooks run at various times during the lifecycle of the component. Depending on your needs you can run code when those events occur. Some are more useful and more commonly used than others. Let’s look at some examples of the hooks which I believe are most useful.

## `ngOnInit`

Let’s start with what is likely the most common lifecycle hook, `ngOnInit`. This hook is used to initialize certain information or data used in the component. It’s run once, after `ngOnChanges` is run. If you’ve worked in an Angular component at all, you’ve likely seen and used `ngOnInit`.

There is one main “gotcha” to remember with this lifecycle hook. If the component’s data is changed, but it remains on the screen, `ngOnInit` does not run again. This includes when a component is used for a route in your app. Let’s say we have a `DetailComponent` that shows the detail of a user. The `userId` is pulled from the route params and the data is shown on the page. If you route to the detail of a new user, the data will need to change but `ngOnInit` will not be run again, even though the route changes.

Here’s a brief example of an `ngOnInit` method:

```ts
ngOnInit() {
  this.results = this._dataService.getResults();
}
```

## `ngOnChanges`

The next hook we’ll look at is `ngOnChanges`. This hook is used to respond to changes to the data that’s passed in to a component. It is run any time the data-bound properties of the component change. The first time it's run is before `ngOnInit` is run.

A good use case for `ngOnChanges` is when a component has some data passed in, and subsequent calculations need to be made with that data to display in the component. If you were to make the calculations in the `ngOnInit` hook, the data would not update as you expect or desire when the inputs are changed. This is due to `ngOnInit` only being run once.

Here’s an example of what may happen in the `ngOnChanges` method:

```ts
ngOnChanges(changes: SimpleChanges) {
  this.total = this.inputOne + this.inputTwo;
}
```

The `ngOnChanges` hook takes an optional argument of type `SimpleChanges`. Each attribute on the `SimpleChanges` object has three attributes: `currentValue`, `previousValue`, and `firstChange`. Those three attributes are included on an interface called `SimpleChange`. These attributes are pretty self explanatory, and allow you to react however you need to in your components. The only attributes present on the `SimpleChanges` object are ones that changed in that particular run. So, if `inputOne` changes, but not `inputTwo`, then the object would look like this:

```json
{
  "inputOne": {
    "previousValue": 1,
    "currentValue": 2,
    "firstChange": false
  }
}
```

If the data in your component should be re-calculated when the inputs change, use the `ngOnChanges` hook.

## `ngAfterViewInit`

The `AfterViewInit` hook allows you to respond when the component’s view and child views are visible on the screen. This hook runs just once, after the first time `ngAfterContentChecked` is run.

The `ngAfterViewInit` hook is perfect when you need to reference an element of the component’s template inside the TypeScript class. If you try and reference the element in the `ngOnInit` hook, there is a good chance that the variable will still be `undefined`. Waiting until the `ngAfterViewInit` hook runs ensures that the element will be in the screen, provided it’s not been removed from the screen with the `*ngIf` directive.

Here’s an example of using the `ngAfterViewInit` hook:

```ts
export class DemoComponent implements AfterViewInit {
  @ViewChild('myElement') myElement: ElementRef;

  ngOnInit() {
    console.log(this.myElement); // undefined
  }

  ngAfterViewInit() {
    console.log(this.myElement); // ElementRef { ... }
  }
}
```

## `ngOnDestroy`

The `ngOnDestroy` hook is run when Angular removes the component from the application. It can be used for cleanup of the component, including unsubscribing from long-lived observables or removing event handlers.

It’s important to remember that Angular needs to remove the component from the app for the hook to run. If you refresh or close the browser tab, the component is technically removed from the browser, but Angular didn’t control the removal of the component. Thus, the `ngOnDestroy` hook is not run.

Here’s an example of using the `ngOnDestroy` hook:

```ts
private subscription;

ngOnInit() {
  this.subscription = this.someService.appState.pipe().subscribe();
}

ngOnDestroy() {
  this.subscription.unsubscribe();
}
```

- Best practice is to subscribe to observables using the `async` pipe. If you do that, there’s no need to clean up subscriptions in the `ngOnDestroy` hook. However, some situations require you to subscribe to the observable in the TypeScript file and this will allow you to unsubscribe from the Observable and prevent memory leaks in your app.

## Conclusion

In my experience, these are the most used lifecycle hooks. Understanding how they are used and in what situations will allow you to be most effective when writing your Angular apps. The other hooks I mentioned at the beginning of the article can also be helpful, but aren’t as common as the four covered here