112

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>
        <label>Name:</label>
        <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 { }
PaulMest
  • 12,925
  • 7
  • 53
  • 50
Chaitanya Chitturi
  • 1,129
  • 2
  • 7
  • 8

14 Answers14

208

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,
// ...
}
ktretyak
  • 27,251
  • 11
  • 40
  • 63
  • Restarting the angular application then solved the problem – SwissCodeMen Nov 16 '22 at 18:53
  • 3
    I'm getting really sick of Typescript trying to completely turn Javascript into a new, fully typed language. It's not. They need to make it far easier to find and turn off these features. – Tim Hardy Jan 24 '23 at 23:24
  • 1
    The Angular documentation examples suggest coding it like the OPs question. So its surprising to me that The default template for an Angular 16 project has this option as true. https://angular.io/guide/typed-forms – Michael Lang Jun 06 '23 at 04:18
  • If TypeScript is trying to be so terse, why not just use Java. I don't get the whole, let's use Javascript, it's so much simpler than Java and then now ... let's make it more like Java. Makes no sense – Harlin Jul 21 '23 at 12:22
102

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

UI_Dev
  • 3,317
  • 16
  • 46
  • 92
Youssef
  • 2,866
  • 1
  • 24
  • 20
  • thanks! I'm new in angular and things like this are frustrating stuff :snif:. In my case it was from ```
    Password is required
    ``` to ```
    Password is required
    ``` (I have to remove the dot too)
    – Rodrigo Dec 22 '22 at 16:57
  • 1
    Please reverse the edit, because an extra dot is actually required for optional chaining. It's either `errors?.['required']` or `errors['required']`. – Tortila Jan 16 '23 at 18:14
  • It needs `.` after the question mark `firstName.errors?.['required']` – wael razouk Jan 26 '23 at 08:10
  • 1
    Any idea why angular has changed from `errors?.required` to `errors?.['required']`? – Rakesh Sojitra Apr 24 '23 at 05:42
  • 1
    @RakeshSojitra [ValidationErrors](https://angular.io/api/forms/ValidationErrors) has index signature, and in TS 4.2 [noPropertyAccessFromIndexSignature](https://www.typescriptlang.org/tsconfig#noPropertyAccessFromIndexSignature) flag was released. – Tortila Jul 31 '23 at 22:28
11

Change this key value to false in tsconfig.json file

"noPropertyAccessFromIndexSignature": false

10

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>
H.Azizkhani
  • 893
  • 10
  • 11
7

In angular 14.0.4, it only worked for me with

<div *ngIf="user?.errors?.['required'] ">First Name is required</div>
user2789115
  • 71
  • 1
  • 2
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>
Saeid Amini
  • 1,313
  • 5
  • 16
  • 26
Aravind T
  • 41
  • 1
1

Please use f['fName'].errors instead of f.fName.errors.

<input id="name" type="text" formControlName="fName" class="form-control" [ngClass]="{'is-invalid':submitted && f['fName'].errors}"/>
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
0

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>
0

worked in my case.

<div *ngIf="firstName.errors?.required">
        <b>First Name is required</b>
      </div>
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 13 '22 at 01:04
  • It worked in your case because you have `"noPropertyAccessFromIndexSignature": false,` so please do remove your answer since it isn't useful – Raphaël Balet Aug 29 '22 at 15:27
0

Check on this example

file.ts

formBuilderInit() {
        this.form = this.formBuilder.group({
            first_name: [null, Validators.required],
            middle_name: [],
            last_name: [null, Validators.required],
            email: [],
            tel: [null, [Validators.required, Validators.pattern('^[0-9]{12}$')]],
        });
    }

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

file.html

<mat-label for="tel">Telephone</mat-label>
    <mat-form-field>
       <input
          type="number"
          matInput
          formControlName="tel"
          class="form-control"
          placeholder="Ex: 250722353933"
          [ngClass]="{ 'is-invalid': submitted && f['tel'].errors }"
       />
       </mat-form-field>
       <div *ngIf="submitted && f['tel'].errors" class="invalid-feedback">
        <div *ngIf="f['tel'].errors['required']">Telephone Number is required</div>
            <div *ngIf="f['tel'].errors['pattern']">
               Phone number must be at least 12 digit numbers
            </div>
       </div>
Bercove
  • 987
  • 10
  • 18
0

Dont forget insert dot (.) between erros? and ['required'] like below

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

For mores informations (angular 15) goes this link: https://angular.io/guide/form-validation

  • You could copy paste an example from the docs in order to help the viewer pinpoint the exact location. Just mentioning it as a possible improvment in your answer. – jimas13 Jan 17 '23 at 21:19
0

Angular form validation with error property of ngmodel in newer version of angular include following tag has required attribute validation *<div ngIf="phone.hasError('required')">phone number is required this pattern ('required') helped me in resolving the error

user2001
  • 1
  • 1
0

add the following line to tsconfig.json file, or set it to false if already exist

"noPropertyAccessFromIndexSignature": false,
-1

Bro just use f['fullName'].errors[required] instead of f.fName.errors.required

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

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Sep 27 '22 at 20:48