Tips on making a forced call to `super.ngOnDestroy`

I am utilizing an abstract class to prevent redundant code for unsubscribing observables. Here is what it looks like:

export abstract class SubscriptionManagmentDirective implements OnDestroy {
  componetDestroyed = new Subject<void>()

  constructor() {}

  ngOnDestroy(): void {
    this.componetDestroyed.next()
    this.componetDestroyed.unsubscribe()
  }
}

Occasionally, I forget to call super.ngOnDestroy() when overriding ngOnDestroy, causing the subscriptions to misbehave.

To ensure that un-subscriptions are properly called in extending components, I have added unit tests. However, remembering to add these tests can be a challenge.

Therefore, my query is,

  • Is there a way to mandate the calling of super.ngOnDestroy() whenever the component is extended?
  • Or is there a method to create a unit test for the abstract class that would automatically be applied to any component that extends it?

Your assistance on this matter would be greatly appreciated. Thank you.

Answer №1

In my opinion, a useful approach would be to include

"noImplicitOverride": true
in your tsconfig file. While it may not directly remind you to call a super method, it will require you to be explicit about overriding methods. This means that if you try to override a method without using the override keyword, a compilation error will be thrown. Ultimately, it is left up to the developer to determine whether or not the super method should be called.

https://www.typescriptlang.org/tsconfig#noImplicitOverride

Answer №2

  1. Unfortunately, there is no automated method to call a function from an abstract class.

  2. The best approach is to conduct unit testing in isolation. You can achieve this by creating a test class that extends the abstract class and then focusing on testing the ngOnDestroy method. This method should suffice for your testing needs.

Answer №3

There's a somewhat unconventional and messy method that comes to mind. TypeScript itself enforces the super() call in the constructor, which could potentially be leveraged.

class Foo {
  constructor() {
    const oldNgOnDestroy = this.ngOnDestroy;

    this.ngOnDestroy = function() {
      console.log("decorated ngOnDestroy");
      return oldNgOnDestroy();
    }.bind(this);
  }

  ngOnDestroy() {
    console.log("original ngOnDestroy");
  }
}

class Bar extends Foo {
  constructor() {
    super();
  }
}

class Baz extends Foo {
  constructor() {
    super();
  }

  ngOnDestroy() {
    console.log("custom ngOnDestroy");
  }
}

const bar = new Bar();
bar.ngOnDestroy();
const baz = new Baz();
baz.ngOnDestroy();

This approach may not be elegant, but it gets the job done in a roundabout way.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

showing pop-up notification in Angular

I am utilizing the ngx-alert service to show an error message if the supplied credentials do not match any user account in my database. This is my current process: if (this.check.data.length == 0) { this.alert.danger('User does not exist' ...

Having difficulty incorporating TypeScript into Vue

A little while ago, I set up a vue project using vue init webpack . and everything was running smoothly. Recently, I decided to incorporate typescript and ts-loader. I created a file in the src directory with the following content: declare module '* ...

The filtering process of an array using the filter() method is effective, however, it does not result in any visible changes on

script.js searchVideo = (keyword) => { this.input = keyword; if(this.items.length == 0){ this.filteredItems = []; } if(!this.input){ this.filteredItems = this.items; } const args = this ...

Why is this chip-list not functioning properly in my Angular 14 and Angular material application?

I'm currently developing a form using Angular 14. My goal is to incorporate a field with Angular Material chips. Within the component's Typescript file, I have the following code: constructor(private fb: FormBuilder,) { } public visible: boole ...

What is the best way to include a button at the bottom of a Material UI table?

I've been working with Material UI in React TypeScript and I'm having trouble adding a button at the bottom that leads to a form. Despite my attempts, I haven't been successful. Can someone please help me with this? I just need a simple butt ...

SmartEdit functions properly when spartacus is running using yarn start --ssl, but does not work without SSL enabled

I followed the smartedit setup instructions at and everything works well when I start the Spartacus server with yarn start --ssl. However, if I start the server with just yarn start, the storefront does not appear. See image here for reference ...

'Error: The type is missing the 'previous' property - Combining TypeScript with ReactJS'

I am quite new to using reactjs and ts. While I understand the error that is occurring, I am unsure of the best solution to fix it. Currently working with reactjs, I have created an: interface interface IPropertyTax { annul: { current: number; p ...

Select information from an array and store it within an object

I want to extract all objects from an array and combine them into a single object. Here is the current array data: userData = [ {"key":"firstName","checked":true}, {"key":"lastName","checked":true ...

Value returned by Typescript

I have been attempting to retrieve a string from a typescript function - private _renderListAsync(): string { let _accHtml: string=''; // Local environment if (Environment.type === EnvironmentType.Local) { this._getMockLi ...

Tips for extracting a particular subset from an array containing JSON objects using Angular

Hey there, I have a collection of JSON objects and I've been able to showcase them one by one using Angular (in this case, I'm building a blog). The JSON objects are retrieved through an HTTP GET request. On my landing page, I display the blog ...

Angular 7 throwing errors of undefined variables

I encountered an error message that says Property 'country' does not exist on type 'ViewComponent'. Did you mean 'country$'? I'm at a loss on how to resolve this issue. I understand that there is an undefined variable ca ...

What methods does VS Code use to display type errors in TypeScript given that TypeScript requires compilation?

TypeScript is a language known for being statically typed, giving it the ability to verify types during the compilation process and translate the code into JavaScript. Considering this, how is it possible for VS Code to detect type errors without the code ...

Tips for efficiently handling state across various forms in separate components using only one save button within a React-Redux application

I am currently developing an application that combines a .NET Core backend with a React frontend, using React Hook Form for managing forms. Unlike typical single-page applications, my frontend is not built in such a way. On a specific page of the applicat ...

Can conditional content projection (transclusion) be achieved in Angular 2+?

How can I set default content that will only display if content is not transcluded? Consider the following component template: <article> <header> <ng-content select="[header]"></ng-content> </header> < ...

'Unable to locate the identifier "system" in Angular 2' - troubleshoot this unique error

My routes file contains a reference to 'system' which is causing an error in my Visual Studio Code. The error states that it cannot find the name 'system'. I have attached a screenshot for reference: ...

TypeScript does not properly validate the types of defaultProps

When working with TypeScript 3.0, I consulted the documentation at https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html The recommendation is to use static defaultProps: Pick<Props, "name"> as an explicit type annotation ...

Error occurs in Azure Function Linux Nodejs when trying to use @azure/storage-blob as it cannot read the property 'startsWith' of undefined

While testing my Azure Nodejs Linux function locally, I encountered this issue with the code snippet below: import { BlobServiceClient } from "@azure/storage-blob"; const connectionString = process.env[ "AZURE_STORAGE_CONNECTION_STRING&qu ...

Encountering a POST 504 error while attempting to proxy an Angular application to a Node server

error message: Failed to connect to http://localhost:4200/api/user/login with a 504 Gateway Timeout error. Encountered this issue while attempting to set up a login feature in my Angular application and establish communication with the Express backend. Th ...

Tips for setting up nextjs with typescript to utilize sass and nextjs font styles

I am attempting to configure a Next.js TypeScript app to work with Sass and a font in Next.js. I have been following the steps outlined in this article. Without the font module, styles are working correctly. Below is my next.config.js without the font co ...

What is the best way to integrate model classes within an Angular module?

I have a few classes that I want to keep as plain bean/DTO classes. They are not meant to be display @component classes, @Pipe classes, or @Directive classes (at least, that's what I believe!). I am trying to bundle them into a module so that they ca ...