Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

144
Views
Using a base component to unsubscribe from all observable subscriptions

In an Angular app, we're using a Base Component to unsubscribe from most of our app's observable subscriptions. If a component subscribes to an observable, that component will extend the Base Component. My thought is that this keeps observable subscriptions alive until the entire application is destroyed, rather than until each component is destroyed:

base.component.ts:

import { Subject } from 'rxjs';
import { OnDestroy, Component } from '@angular/core';

export abstract class BaseComponent implements OnDestroy {
  protected unsubscribe$ = new Subject<void>();

  ngOnDestroy(): void {
    this.unsubscribe$.next();
    this.unsubscribe$.complete();
  }
}

the-rest-of-our-components.ts:

import { Component, OnInit } from '@angular/core';
import { MyService } from 'src/app/services/my.service';
import { BaseComponent } from '../base/component/base-component';

export class myComponent extends BaseComponent implements OnInit {
  myProperty: string;

  constructor(
    private myService: MyService,
  ) {
    super();
  }
  ngOnInit(): void {
    this.myService.doStuff$
      .pipe(takeUntil(this.unsubscribe$)) // take until baseComponent's unsubscribe$
      .subscribe((data) => {
        this.myProperty = data;
      });
  }

If many components extend BaseComponent and utilize its unsubscribe$ Subject, does that mean all of my subscriptions only get unsubscribed when the entire application is destroyed (aka user closes the tab or navigates away from web app, thus Base Component is destroyed), rather than when individual components get destroyed?

Is this a strategy you've seen before, and is it advisable? If it works as I'm assuming, this means all of our subscriptions across the application stay active until the whole app is destroyed. I see how, depending on our needs, that might be a bad thing or a good thing.

Bonus question: is Base Component going to act like a singleton? AKA if multiple components simultaneously extend BaseComponent, will they all be using the same instance of unsubscribe$ or will there be multiple instances of unsubscribe$ (one per component)?

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

I assumed this would work, but we all know where assumptions get you, so I made a test: https://stackblitz.com/edit/angular-ivy-ueshwz?file=src/app/extended/extended.component.ts

It works, as in subscriptions get destroyed when individual components get destroyed.


We make a service that holds a subject we can subscribe to, and a value we can change with the subscription, to show that the subscription exists:

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/internal/Subject';

@Injectable({ providedIn: 'root' })
export class UpdateService {
  subject = new Subject<void>();
  value = 0;
}

In the root we'll fire the subject every second, and have a component that we can toggle on and off

export class AppComponent implements OnInit {
  extCompOpen = true;

  constructor(public update: UpdateService) {}

  ngOnInit() {
    interval(1000).subscribe(() => this.update.subject.next());
  }
}
<app-extended *ngIf="extCompOpen"></app-extended>
<button (click)="extCompOpen = !extCompOpen">Toggle Component</button>

<p>This counter will keep going up as long as the subscription exists:</p>
<p>{{ update.value }}</p>

Then we'll use an extended component to tick that value up by 1 with a subscription

export class ExtendedComponent extends BaseComponent implements OnInit {
  constructor(private update: UpdateService) {
    super();
  }

  ngOnInit() {
    this.update.subject.pipe(takeUntil(this.unsubscribe$)).subscribe(() => {
      this.update.value++;
    });
  }
}
<p>Extended component exists!</p>

Neat, closing the component stops the ticker, so the subscription has been unsubscribed.


Bonus question: BaseComponent does not act like a singleton, when you create an instance of an object it does not create shared instances of parent classes. Extending a class just adds properties and methods to that instance.


I'm not sure if I would recommend this, if someone overrides ngOnDestroy() they need to call super.ngOnDestroy(), which may be easy to forget. It's only four lines of code, probably better to explicitly put it in every component that needs it. Manual subscriptions should be pretty rare anyway, if you're using the async pipe.

about 4 years ago · Juan Pablo Isaza Report

0

I solved this in a project doing the following:

In base.component:

private sub: any = {};

ngOnDestroy() {
  Object.keys(this.sub).map(item => {
     this.sub[item].unsubscribe();
  })
}

Then in any component that extends:

this.sub.myService = this.myService.doStuff$.subscribe(......

With this method, the subscription stay active until the component is destroyed.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!