takeUntilDestroy in Angular v16
takeUntilDestroy is a new feature coming in Angular 16. In this article, we will explore how it works, and learn how to use it.

takeUntilDestroy in Angular v16
takeUntilDestroy is a new feature coming in Angular 16. In this article, we will explore how it works, and learn how to use it.


When subscribing to observables (especially in our components) we have to unsubscribe on destroy to prevent any memory leaks in our application. We can do it in a few ways, and now a new sheriff is in town! In most cases, it is probably the easiest to use since it does many things automatically.
Previous methods of unsubscribing from subscriptions added a lot of boilerplate to our classes, which reduced readability. For example, consider the following subscription that needs to be safely handled:
<>Copyexport class Component implements OnInit { data; ngOnInit(): void { this.service.getData().subscribe( response => this.data = response. ) } }
We could use takeUntil
operator with additional subject
:
<>Copyexport class Component implements OnInit, OnDestroy { data; destroyed = new Subject() ngOnInit(): void { this.service.getData() .pipe( takeUntil(this.destroyed), ) .subscribe( response => this.data = response ) } ngOnDestroy(): void { this.destroyed.next(); this.destroyed.complete(); } }
Or any other method to deal with an open subscription — there is many of them, but as long as you are calling the subscribe
in the component’s class you will end up with many boilerplate code.
Luckily that’s when new operator comes into play in Angular 16 — the takeUntilDestroy
. This pipe-able operator functions similarly to the example above with takeUntil(this.destroyed)
, but with almost zero additional code required!
Injectable OnDestroyLink to this section
Angular 16 introduced a flexible ngOnDestroy
, which makes the OnDestroy
hook injectable.
<>CopydestroyRef = inject(DestroyRef);
This allows us to inject it into our components instead of using it as a method. As a result, we can modify our takeUntil
example to something like this:
<>Copyexport class Component implements OnInit { destroyRef = inject(DestroyRef); ngOnInit(): void { const destroyed = new Subject(); this.destroyRef.onDestroy(() => { destroyed.next(); destroyed.complete(); }); this.service.getData() .pipe(takeUntil(destroyed)) .subscribe(response => this.data = response) } }
This basically means that we don't need to implement the ngOnDestroy
method in our component. All the "additional" code can be wrapped within a pipe-able operator, which is what happened!
takeUntilDestroyLink to this section
Now we can use the takeUntilDestroy
operator, which is super convenient. Just add it to the pipe without passing anything, and it will automatically pick up the right OnDestroy
for the current context — using injectable OnDestroy.
<>Copyimport { takeUntilDestroyed } from '@angular/core/rxjs-interop'; export class Component implements OnInit{ data; constructor(private service: DataService) { this.service.getData() .pipe(takeUntilDestroyed()) .subscribe(response => this.data = response) } }
That is all!
Passing OnDestroy referenceLink to this section
In some cases, we may want to react to the destroy event of another component. For example, consider a scenario where a parent component has a subscription that needs to remain active as long as the child component is on the screen. In this case, we can inject DestroyRef
in the child component:
<>Copyexport class Child { destroyRef = inject(DestroyRef); }
We can use the new takeUntilDestroyed operator in the parent component to close the subscription by passing the reference to the DestroyRef
of the child component. Here is an example implementation for the parent component:
<>Copyexport class Parent { @ViewChild(Child) child: Child; ngOnInit(): void { interval(1000) .pipe(takeUntilDestroyed(this.child.destroyRef)) .subscribe((count) => console.log(count)); } }
The count will be logged to the console as long as the Child
component exists. Upon its destruction, the subscription in the Parent
will be stopped.
Have fun and enjoy Angular 16 features! 🤓
Comments (0)
Be the first to leave a comment
About the author

Hey, I'm a frontend developer, passionate about good design for both the code and UX/UI side of things. I am mainly involved in Angular, rxjs, typescript subjects.

About the author
Maciej Wojcik
Hey, I'm a frontend developer, passionate about good design for both the code and UX/UI side of things. I am mainly involved in Angular, rxjs, typescript subjects.
About the author

Hey, I'm a frontend developer, passionate about good design for both the code and UX/UI side of things. I am mainly involved in Angular, rxjs, typescript subjects.