'Property 'fName' comes from an index signature, so it must be accessed with ['fName']

These are my files. I am getting this error can someone help me.

Error: src/app/app.component.html:5:123 - error TS4111: Property 'fName' comes from an index signature, so it must be accessed with ['fName'].
        <input id="name" type="text" formControlName="fName" class="form-control" [ngClass]="{'is-invalid':submitted && f.fName.errors}"/>

component.html

<form [formGroup]="surveyForm" (ngSubmit)="onSubmit()">
  <div>
    <lable>Name:</lable>
    <input id="name" type="text" formControlName="fName" class="form-control" [ngClass]="{'is-invalid':submitted && f.fName.errors}"/>
    <div *ngIf="submitted && f.fName.errors" class="form-control">first name is required</div>
  </div>
</form>

component.ts

import { Component, OnInit } from '@angular/core';
import { FormControl, FormBuilder, FormGroup, Validators} from '@angular/forms';
@Component({
selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
  })
  export class AppComponent implements OnInit{
    surveyForm!: FormGroup;
    submitted= false;

 constructor(private  formBuilder: FormBuilder){}

 ngOnInit(){
 this.surveyForm = this.formBuilder.group({
   fName: ['',Validators.required]
  });
}  
//name = new FormControl('');
get f() { return this.surveyForm.controls; }

 onSubmit() {
 this.submitted = true;

// stop here if form is invalid
if (this.surveyForm.invalid) {
    return;
}

// display form values on success
alert('SUCCESS!! :-)\n\n' + JSON.stringify(this.surveyForm.value, null, 4));
}

 onReset() {
this.submitted = false;
this.surveyForm.reset();
}}

module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { FormsModule } from '@angular/forms';
//import { FormBuilder } from '@angular/forms';

@NgModule({
 declarations: [
   AppComponent
 ],
imports: [
 BrowserModule,
 AppRoutingModule,
 FormsModule,
 ReactiveFormsModule,
 //FormBuilder
 ],
//declarations: [AppComponent],
  providers: [
 //FormBuilder
 ],
 bootstrap: [AppComponent]
 })
 export class AppModule { }


Solution 1:[1]

In my opinion, this is a completely unnecessary feature in TypeScript. To disable it, you need to change the file tsconfig.json:

"compilerOptions": {
// ...
  "noPropertyAccessFromIndexSignature": false,
// ...
}

Solution 2:[2]

let clarify what is the issue. We are talking about a template-driven form validation. You need to validate something, let's say to ensure that a field is required (call it firstName). Note that from Angular v13, it changed a bit from an old code like this:

<div *ngIf="firstName.errors?.required">First Name is required</div>

to this

<div *ngIf="firstName.errors?.['required']">First Name is required</div>

As a reminder, the '?' is to ensure that the errors object is not null.

More details are here: https://angular.io/guide/form-validation

Solution 3:[3]

Angular 13 Form Validation with Reactive Forms Example

add form() getter for easy access to form fields in *.component.ts file

//convenience getter for easy access to form fields
get form(): { [key: string]: AbstractControl; }
{
    return this.signInForm.controls;
}

Access to email field errors example

form['email'].errors

form['email'].errors['required']

form['email'].errors['email']

signInForm HTML example

<form [formGroup]="signInForm" (ngSubmit)="onSubmit()">

    <div class="form-group">
        <label for="email">Email</label>
        <input type="email" formControlName="email" class="form-control"
            [ngClass]="{ 'is-invalid': submitted && form['email'].errors }" />
        <div *ngIf="submitted && form['email'].errors" class="invalid-feedback">
            <div *ngIf="form['email'].errors['required']">
                Field is required
            </div>
            <div *ngIf="form['email'].errors['email']">
                Email format is invalid
            </div>
        </div>
    </div>

    <div class="form-group mt-3">
        <label for="password">Password</label>
        <input type="password" formControlName="password" class="form-control"
            [ngClass]="{ 'is-invalid': submitted && form['password'].errors }" />
        <div *ngIf="submitted && form['password'].errors" class="invalid-feedback">
            <div *ngIf="form['password'].errors['required']">
                Password is required
            </div>
        </div>
    </div>

    <div class="mt-3 d-flex justify-content-between">
        <button type="submit" [disabled]="isLoading" mat-flat-button color="primary">
            <span *ngIf="isLoading" class="spinner-border spinner-border-sm mr-1"></span>
            Sign in
        </button>
    </div>

</form>

Solution 4:[4]

Answer:

<span *ngIf="username?.errors?.['required']">Name is required</span>
<span *ngIf="username?.errors?.['minlength']">
    Name must be 3 
charchters</span>

Here is the answer to the question Error: src/app/reactive-signup/reactive-signup.component.html:16:52 - error TS4111: Property 'required' comes from an index signature, so it must be accessed with ['required'].

<span *ngIf="username?.errors.required">
    Name is required
</span>

Solution 5:[5]

Angular 13 Form Validation with Reactive Forms and Form Builder, I had found the solution in Angular document, they have some different with Angular 12, you can try this:

<div *ngIf="submitted && surveyForm.get('fName')?.valid" class="form-control">first name is required</div>

Solution 6:[6]

worked in my case.

<div *ngIf="firstName.errors?.required">
        <b>First Name is required</b>
      </div>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ktretyak
Solution 2 Youssef
Solution 3 H.Azizkhani
Solution 4 Saeid Amini
Solution 5 thisisminh
Solution 6 Abhishek kumar