🧩 Implementation:
Here an on destroy service for being used in rxjs and angular component for unsubscribing observables.
@Injectable()
export class DestroyService extends Subject<void> {
ngOnDestroy() {
this.next();
this.complete();
}
}
🧩 Question:
How Angular calls ngOnDestroy() in this pattern? Even though DestroyService is a service and extends Subject, how does Angular still invoke ngOnDestroy()?
💡 Answer:
Here's the key idea:
Even though
DestroyServiceextendsSubject(which is not a component or directive), Angular still calls itsngOnDestroy()method if the service is provided at the component level.
🔑 Why ngOnDestroy() Gets Called in a Service
✅ Angular will call ngOnDestroy() if:
- The class implements
OnDestroy - AND it is a provider on a component or directive
Example:
@Component({
selector: 'app-foo',
providers: [DestroyService]
})
export class FooComponent {
constructor(private destroy$: DestroyService) {}
}
Then Angular treats the service like a directive-level provider, and because it has ngOnDestroy():
Angular will call that method when the component is destroyed.
🧠 Why It Works Even Though It Extends Subject
-
Subjecthas nongOnDestroy(). That's fine. - You're extending
Subjectand addingngOnDestroy()yourself. - Angular doesn’t care that it extends
Subject— it just sees:- “This class was provided in the component”
- “It has
ngOnDestroy()” - ✅ Call it when the component is destroyed
🔁 Summary
-
DestroyServiceis a service, but it's scoped to the component usingproviders: [DestroyService] - It has a custom
ngOnDestroy()method - Angular calls
ngOnDestroy()on component-scoped providers - So you get an automatic, injectable "destroy notifier" for use with
takeUntil()
This is a neat Angular trick that combines:
- Lifecycle hooks
- Dependency injection
- RxJS
into a reusable, composable unsubscribe mechanism.
Top comments (0)