Enhancing component and view functionality in Angular

Recently, I started working on Angular 11 and encountered a simple yet challenging question. Despite my best efforts, I have been unable to find a suitable answer. In an attempt to utilize Object-Oriented Programming (OOP) concepts within Angular, I created a base interface with over 20 fields.

export interface IBaseOperator{
    type:EOperatorType;
    firstname:string;
    lastname:string;
    date:string;
    nic:string;
    // Additional fields are omitted for brevity
}

This base interface serves as the foundation for more than 6 child interfaces. While I will not list all of them here, I will provide examples:

export interface IStaff extends IBaseOperator{
    empId:string;
    // Additional fields
}

export interface IContractor extends IBaseOperator{
    regId:string;
    joinedDate:string;
    // Additional fields
}

When creating a view in HTML for data input, I found myself duplicating <input> fields for both IBaseOperator and its child interfaces in each component. This resulted in redundant code where the fields from IBaseOperator were repeated in all child components. Furthermore, the same functions for save(), update(), delete() had to be duplicated across all 6 children, albeit with slightly different initializations. Currently, my approach is as follows:

For Staff component

this.operatorForm = this.fb.group({
      firstname: ['', Validators.required],             
      lastname: ['', Validators.required],              
      date: ['', Validators.required],                  
      nic: ['', Validators.required],                   
      
      type:[EOperatorType.STAFF,Validators.required]    
      empId: ['', Validators.required]                 
    });

For contractor component

this.operatorForm = this.fb.group({
      firstname: ['', Validators.required],             
      lastname: ['', Validators.required],              
      date: ['', Validators.required],                  
      nic: ['', Validators.required],                   
      
      type:[EOperatorType.CONTRACTOR,Validators.required]   
      regId: ['', Validators.required]                  
      joinedDate: ['', Validators.required]             
    });

These repetitive patterns present several challenges:

  1. Duplicated code across all 6 HTML and TypeScript files
  2. Any changes to the IBaseOperator interface necessitate modifications in all 6 components
  3. Wastage of time and resources due to unnecessary repetition

My query revolves around the feasibility of implementing inheritance in Angular components (both in HTML and TypeScript). Is it possible to consolidate common <input> fields (IBaseOperator) from all child components into a single BaseComponent.html, while also inheriting common functions from a shared BaseComponent.ts? How can this be achieved effectively?

I eagerly await your insights and guidance. Thank you.

Answer №1

Using the 'extends' keyword allows for inheritance of common fields and methods

Take a look at this example where a formgroup is extended to minimize declaring form controls multiple times

export class ParentComponent {
  form:FormGroup
  date= ''

  commonfunction(){
    
  }
  constructor(protected fb: FormBuilder) {
    this.form = this.fb.group({
      date: ['', Validators.required],                  // IBaseOpertor
    })
  }
}
export class ChildComponent extends ParentComponent {
  //Inherits properties from parent component like 'form' and 'date'
  firstname= ''
  lastname= ''
  nic= ''
  empId= ''

  constructor(protected fb: FormBuilder) {
    super(fb) //runs parentComponent constructor
    this.commonfunction() //inherits from parent
    this.form = this.fb.group({
      ...this.form.controls, //form initialized due to super() call
      firstname: ['', Validators.required],             // IBaseOpertor
      lastname: ['', Validators.required],              // IBaseOpertor
      nic: ['', Validators.required],                   // IBaseOpertor
      empId: ['', Validators.required]                  // IStaff
    });
  }
}

The child component's form property includes the control for 'date' because of the usage of spread syntax with ""...this.form.controls""

Answer №2

To show an editable form, one option is to utilize a library like . By passing various fields, along with a standard set, as input to a versatile component that presents the form, you are employing composition over inheritance - which aligns with object-oriented programming principles.

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

Working with JSON data in Angular 2 constructor

When sending a JSON response from the server, it is in the format shown below: {id: Int, name: String, childJSON: String} I want to map this data to the following TypeScript classes: export class Student{ constructor(public id: string, ...

Opt for Observable over Promise in your applications

I have implemented this function in one of my servlets: private setValues() { this.config.socket.on('config.weather', (values:any) => { console.log(values); } However, I would like to refactor it to something like this: private se ...

Setting Angular 2+ FormGroup value in a child component form using data passed from the parent

As a beginner in coding, I encountered an issue with sharing a form component between an add member and edit member component. While copying the form code into each component works fine, it goes against the DRY principle and could lead to banning from furt ...

Struggling to integrate D3.js with React using the useRef hook. Any suggestions on the proper approach?

I'm currently working on creating a line chart using d3.js and integrating it into React as a functional component with hooks. My approach involved utilizing useRef to initialize the elements as null and then setting them in the JSX. However, I encou ...

Using Pydantic to define models with both fixed and additional fields based on a Dict[str, OtherModel], mirroring the TypeScript [key: string] approach

Referencing a similar question, the objective is to construct a TypeScript interface that resembles the following: interface ExpandedModel { fixed: number; [key: string]: OtherModel; } However, it is necessary to validate the OtherModel, so using the ...

Incorporate an image icon into an Angular grid

Currently, I am in the process of building a web application using Angular. The main goal is to create a grid and color specific cells based on data input. Below is the snippet of my HTML code: <mat-grid-list cols="10"> <mat-grid-tile * ...

Troubleshooting a Docker EPERM issue while attempting to compile an Angular application within a container

Our team is currently in the process of containerizing our existing stack using Docker and Docker Compose. This is a simplified version of our Docker Compose file with the relevant services: version: '3.8' services: #FO angularproject: c ...

How can a parent component update a child component's prop value in VUE?

I'm facing an issue with managing dynamic props in Vue with TypeScript. Below is my parent component: <script setup lang="ts"> const friends = [ { id: "emanuel", name: "Emanuella e", phone: "08788 ...

Simultaneously press the mouse click and the Enter key

Looking to enhance the accessibility features on my website, one area I am focusing on improving is using tab and enter keys to select and activate buttons. However, the current method I have implemented is not as elegant as I would like: <a (click)=&q ...

Utilize the function specified in an external file

In my project, I have a typescript file named "menuTree.ts" which compiles to the following JavaScript code: define(["require", "exports"], function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var Menu ...

What is the best way to extract a value from an input within a filter?

I am currently utilizing ngx-easy-table in my application. I am trying to retrieve the input filter value on keyup event, but I have not been able to find any helpful information in the documentation. Does anyone have any insights or suggestions on how to ...

Type with self-reference in index

Looking to create an interface with a mix of known and unknown members that should all have the same type. Here's what I have in mind: interface Foo { name?: string; [others: string]: Foo; } This setup would allow me to create something like ...

Tips for expanding the functionality of the d3-selection module using TypeScript

I am currently working on a project that involves TypeScript and d3. I have already installed 'd3' and '@types/d3', and my use of d3 looks like this: import * as d3 from 'd3'; const x = d3.scaleLinear ... Everything was goin ...

Sending an email using Angular is a straightforward process that involves utilizing the built

I need help figuring out how to code a function in Angular or TypeScript that will open Gmail when a specific email address is clicked. I've tried different methods but haven't been successful so far. ...

Issues with Tagged Union Types in Visual Studio Code

Currently, I am working on implementing a tagged union type pattern for my action creators within a redux application. The TypeScript compiles without any issues, however, my code editor, Visual Studio Code 1.26.1, is flagging an error. [ts] Type &ap ...

Is it possible to render several components for a single route in React?

My application has a layout featuring three columns: a navigation column, a toolbox, and a main content area. However, not all of these components are always present. I now want to display different components in each of these columns. Currently, I am har ...

Issue encountered with utilizing the asynchronous pipe in conjunction with a piped observable

I've been working on this Angular component and HTML code, but I'm puzzled as to why nothing is being displayed. The CSS class is being added (as seen in the first line of the HTML), however, despite the service returning data, there are no visib ...

Ensure a field is required if the integer field is not empty in Angular Schema Form

I am currently working on setting up a form using Angular JSON Schema Form. My goal is to make one field (dropdown1) required only when another field (number1) has been filled in. I have managed to successfully get the following form + schema to function p ...

Methods for loading a font just once? (TypeScript / Three.JS)

My goal is to generate 20 text blocks, all using the same font. However, I encountered an error with the new TextGeometry if the font isn't loaded yet. Currently, I have been creating each text block like so: new THREE.TextGeometry(this.text, { ...