Having trouble grasping the concept of Interfaces and dealing with FormGroup problems in Angular?

Apologies if my question is a duplicate, I have found several solutions for the same issue on Stack Overflow, but unfortunately, I struggle to understand them in technical terms.

Problem 1

src/app/models/dataModel.ts:2:5
2     id: number;
      ~~
The expected type comes from property 'id' which is declared here on type 'DataModel'


Error: src/app/models/dataModel.ts:2:5 - error TS2564: Property 'id' has no initializer and is not definitely assigned in the constructor.

2     id: number; 

My dataModal.ts

export class DataModel {
    id: number;
    name?: string;
    gender?: string;
    age?: number;
    address?: string;
    city?: string;
    country?: string;
    status?: string;
    date?: Date;
}

case-details.component.ts

export class CasesDetailsComponent implements OnInit {
  isLoadingResult = true;
  cases: DataModel = { id: null || undefined, name: '', gender: '', age: null || undefined, address: '', city: '' };

. For Problem 1, whenever I use the optional operator ?, the problem disappears and the app runs smoothly. I would like to understand the purpose of using ? and why.

Problem 2

Error: src/app/component/add-case/add-case.component.ts:22:3 - error TS2564: Property 'formGroup' has no initializer and is not definitely assigned in the constructor.

22   formGroup: FormGroup;
     ~~~~~~~~~

When trying to add form data, I initialize it as shown below in add-case.component.ts

export class AddCaseComponent implements OnInit {
  isLoadingResult = true;

  formGroup: FormGroup;
  id = null;
  name = '';
  age = null;
  status = '';
  gender = '';
  genderList = ['Male', 'Female',];
  statusList = [ 'Positive', 'Negative'];
  address = '';
  city = '';
  country = '';


  constructor(private router: Router, private api: ApiService, private formBuilder: FormBuilder) { }

  ngOnInit(): void {
    this.formGroup = this.formBuilder.group({
      name: [null, Validators.required],
      age: [null, Validators.required],
      status: [null, Validators.required],
      gender: [null, Validators.required],
      address: [null, Validators.required],
      city: [null, Validators.required],
      country: [null, Validators.required]
    });
  }



saveRecord(): void {
    this.isLoadingResult = true;
    this.api.addNewCaseDetails(this.formGroup.value).subscribe((response: any) => {
// other stuffs
}

}

package.json

"dependencies": {
    "@angular/animations": "~11.2.8",
    "@angular/cdk": "^11.2.8",
    "@angular/common": "~11.2.8",
    "@angular/compiler": "~11.2.8",
    "@angular/core": "~11.2.8",
    "@angular/forms": "~11.2.8",
    "@angular/material": "^11.2.8",
    "@angular/platform-browser": "~11.2.8",
    "@angular/platform-browser-dynamic": "~11.2.8",
    "@angular/router": "~11.2.8",

tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015",
    "module": "es2020",
    "lib": [
      "es2018",
      "dom"
    ]
  },
  "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true,
    "strictPropertyInitialization": false
  }
}

Can someone please assist me with this?

Answer №1

Your current issue arises from defining a class without initializing its properties, either in the constructor or directly at the point of their definition. The fact that Typescript is displaying this message indicates that you are working in strict mode, which is why you are encountering this error.

In response to your initial query: the '?' in id?: signifies that the property is optional, meaning it does not necessarily need to have a value and can be null. An alternative approach would be to establish a constructor with the id parameter:

constructor(id: number) {this.id = id;}

Regarding your second question, consider relocating the initialization of your form within the body of the constructor:

constructor(private router: Router, private api: ApiService, private formBuilder: FormBuilder) { 
  this.formGroup = this.formBuilder.group({
      name: [null, Validators.required],
      age: [null, Validators.required],
      status: [null, Validators.required],
      gender: [null, Validators.required],
      address: [null, Validators.required],
      city: [null, Validators.required],
      country: [null, Validators.required]
    });
}

Regarding why this practice is considered best, I am currently researching an answer.

Update: After some investigation, I came across this resource: link.

Typescript requires assurance that a property not specified as optional has a value (to avoid 'undefined' errors and runtime technical complications). Rather than moving the formGroup initialization to the constructor, you could also declare it like so:

myFormGroup!: FormGroup // note the ! mark, indicating that the property will be initialized elsewhere other than the constructor.

constructor(...) {}

ngOnInit() {
   this.myFormGroup = this.fb.formGroup({...});
}

Answer №2

I don't have a direct answer for Problem 1.

When addressing Problem 2, my approach would involve setting the parameters outside of the ngOnInit() function.

export class AddCaseComponent implements OnInit {
  isLoadingResult = true;

  id = null;
  name = '';
  age = null;
  status = '';
  gender = '';
  genderList = ['Male', 'Female', 'Transgender'];
  statusList = ['Recoverd', 'Positive', 'Negative', 'Under treatment', 'Dead'];
  address = '';
  city = '';
  country = '';
  matcher = new MyErrorStateMatcher();

  formGroup = this.formBuilder.group({
      name: [null, Validators.required],
      age: [null, Validators.required],
      status: [null, Validators.required],
      gender: [null, Validators.required],
      address: [null, Validators.required],
      city: [null, Validators.required],
      country: [null, Validators.required]
      }};

  constructor(private router: Router, private api: ApiService, private 
              formBuilder: FormBuilder) { }

  ngOnInit(): void {}

Answer №3

Student, have you considered implementing some getter and setter methods to modify the class value? Additionally, I recommend utilizing interfaces to create a model and efficiently work with it.

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

What is the process of integrating socket.io with Angular and how can we establish persistent communication using a socket service in Angular?

Just diving into Angular and trying to retrieve continuous dynamic data from a socket server. The server side seems to be set up correctly, but I'm having trouble actually receiving the data from the socket server. ...

Is there a way to utilize req.query, req.params, or req.* beyond its original scope without the need to store it in a database?

Looking to streamline my code and apply the DRY pattern, I've been working on creating a helper function for my express http methods. The structure of each method is similar, but the req.params format varies between them. Here's how I attempted t ...

Utilize or Bring in an external JavaScript file within Ionic 2

Currently working with Ionic 2 and Typescript Angular 2 and facing an issue. I need to utilize an external JavaScript file located at . How can I import or include this in my project? ...

Issue with loading CSS in Angular 8 upon refreshing the page after building in production

Here is the structure of my index.html: <!doctype html> <html lang="hu"> <head> <meta charset="utf-8"> <title>WebsiteName</title> <base href="/"> <meta name="viewport& ...

Having trouble importing a TypeScript module from the global node_modules directory

I have a library folder located in the global node modules directory with a file named index.ts inside the library/src folder //inside index.ts export * from './components/button.component'; Now I am trying to import this into my angular-cli ap ...

Sharing data among components in Angular 6

I've set up 2 components and a service as outlined below: component-interaction.service.ts @Injectable() export class ComponentInteractionService { public dataSubject = new BehaviorSubject<string>("Test"); getTestData(): Observable<an ...

Guide to inheriting functions from a parent component in Angular 2

Hello, I am a beginner in the realm of angular2 and would appreciate any assistance in refining my vocabulary and terminology. Currently, I have a class that consists of two directives structured as follows: In parent.component.ts, the Parent component i ...

How can you inject the parent component into a directive in Angular 2, but only if it actually exists?

I have developed a select-all feature for my custom table component. I want to offer users of my directive two different ways to instantiate it: 1: <my-custom-table> <input type="checkbox" my-select-all-directive/> </my-custom-table> ...

What is the best way to assign a type based on a variadic type in TypeScript?

TypeScript playground link For my current project, I am designing a custom route handler creator for Express. The goal is to allow passing arbitrary assertions as initial arguments before invoking the route handler callback. Here's an example of how ...

Styling the checked state of a switch in NativeScript/Angular with ngModel/FormBuilder

Let's explore the styling of a switch element within Angular: <Switch class="switch" formControlName="answer"></Switch> One approach involves targeting the switch with checked attribute, setting its background-color and text color accord ...

Variable type linked to interface content type

Is it possible to link two fields of an interface together? I have the following interface: export interface IContractKpi { type: 'shipmentVolumes' | 'transitTime' | 'invoices'; visible: boolean; content: IKpiContent; } ...

Required Ionic form field alert

Currently, I am developing a new app using ionic 3 and I am facing an issue with making inputs mandatory in my ionic-alert controller. Despite going through the ionic-component documentation and api documentation, I couldn't find a solution on how to ...

Eslint is back and it's cracking down on unused variables with no

I've configured eslint to alert me about unused variables rules: { '@typescript-eslint/no-unused-vars': ['error', { args: 'none' }], } Presently, I have a TypeScript class structured like this: import { User } from &ap ...

Switching slides in Ionic 4 with a simple button click

I want to switch slides by clicking a button on my presentation. Here is an example code snippet: <ion-slides> <ion-slide> Slide one <ion-slide> <ion-slide> Slide Two <ion-slide> </ion-slides> <butt ...

how to send both the useState setter and object as props to a child component in React using TypeScript

Having an issue with passing useState setter and object (both together) to the child component. Successfully passed the object by spreading it like this {...object}, but unsure of the syntax to pass the setter along as well. Here's a code example: < ...

Angular CLI - exploring the depths of parent-child component communication

My issue revolves around accessing the 'edit' method of a child component using @ViewChild, but for some reason it's not functioning as expected. Where could I possibly be going wrong? Here are the console logs: Key parts of the CompanyCom ...

Mastering the art of incorporating objects into templates using *ngFor Angular

Whenever I do my *ngFor loop in my HTML template, the data is displaying as [Object Object]. Below is my view with the enumerated data in the developer console: https://i.stack.imgur.com/KXmiI.png This is the snippet of my HTML code: https://i.stack.im ...

Unlocking rotation on a single screen in a react native application can be achieved by altering

I attempted to use react-native-orientation within a webview in order to make it the only view that would rotate. import React, {useEffect} from 'react'; import { WebView } from 'react-native-webview'; import Orientation from "react-na ...

Deployment failure due to undetected development keys in gitignore

I have a TypeScript-coded Express server with three files for keys in the compiled and pre-compiled code: /// dev.ts - development keys const keys = { googleClientSecret: "GOOGLE_KEY", mongoURI: "mongodb+srv://MONGO_K ...

Get ready for 10 AM with the RxJS timer function

I am trying to figure out how to schedule a method in my code using rxjs/timer. Specifically, I want the method to run at precisely 10 AM after an initial delay of 1 minute. However, my current implementation is running every 2 minutes after a 1-minute d ...