From Classes to Functions: Angular 16 Introduces DestroyRef
Attach a callback to the OnDestroy lifecycle any time you want
Introduced in Angular v16.0.0-next.2 (currently at v16.0.0-next.6) is the DestroyRef API which allows you to attach a callback to the onDestroy lifecycle hook, enabling you to take a functional approach to this hook.
Before this, anything that you required to be run when your component was destroyed would go in the ngOnDestroy method of your component class, but now you can attach any code using the inject(DestroyRef) in any valid injection context.
Observables and ngOnDestroy
One of the most common memory leaks when starting to use Observables comes from not unsubscribing to them.
Unlike most of your Components properties, your subscriptions to Observables are not automatically cleaned up and removed when your component is destroyed.
One way to solve this is to have a subscriptions array in your class that you push any long-lived subscription you subscribe to, so on your ngOnDestroy method you would unsubscribe each one. You could create a base class that implements this and extend any component class.
But what about if we needed to add more logic to the ngOnDestroy method? we would need to override it and add call the super() method:
As you can tell, we’re adding boilerplate to be able to unsubscribe “easily” from of any subscription made during the component code execution. This gets more complicated in cases were you need to extend to another class that also will have to extend to this base class to handle Observables.
That’s where DestroyRef comes to help!
Now that we can inject the DestroyRef class, we can attach a callback to the OnDestroy lifecycle any time we want!
But that’s not all!
We could create a new function that can be shared across all your code to do this! (It could even be integrated in some RxJS interop library directly from the Angular team.)
Function inspired from this post by Minko Gechev.
This autoUnsubscribe method will automatically unsubscribe to any Observable you give it, at the time DestroyRef.onDestroy() is called.