Cpt Kitkat
Cpt Kitkat

Reputation: 1402

Why am I getting error in *ngIf of angular reactive form

I understand this is a very stupid question and for someone with my SOF reputation should not be asking.Howvever I am pulling my hair and can't seem to understand what I am doing wrong. I am referring to an example on Stackblitz to create reactive form.

In Stackblitz everything seems fine and my code works fine too.But in vs code I see error Identifier 'nameType' is not defined. '__type' does not contain such a memberAngular Code :

 <div>
<label>Name Type</label>
<mat-select formControlName="nameType" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.prefix.errors }">
  <mat-option *ngFor="let obj of nameTypeSelection" [value]="obj.value"> {{ obj.viewValue }}</mat-option>
</mat-select>
<div *ngIf="submitted && f.nameType.errors" class="invalid-feedback">
        <div *ngIf="f.nameType.errors.required">Name Type is required</div>
      </div>

  // Form Variable for Ind Cust
  indCustregisterForm: FormGroup;
  submitted = false;
  
   ngOnInit() {
    this.indCustregisterForm = this.formBuilder.group({
      prefix: ['', Validators.required],
      nameType: ['', Validators.required],
      firstName: ['', Validators.required],
      middleName: [''],
      lastName: ['', Validators.required],
      gender: ['', Validators.required],
      dateOfBirth: ['', Validators.required],
      citizenship: ['', Validators.required]
    });
  }
  // convenience getter for easy access to form fields of Individual Customer Form
  get f() {
    return this.indCustregisterForm.controls;
  }
  
  onSubmit() {
    this.submitted = true;
    if (this.indCustregisterForm.valid) {
      console.log('Success')
    }

    // stop here if form is invalid
    if (this.indCustregisterForm.invalid) {
     console.log('Error')
      });
      return;
    }

  }
<!-- Individual Customer Form -->
<form [formGroup]="indCustregisterForm" (ngSubmit)="onSubmit()">
  <div>
    <label>Name Type</label>
    <mat-select formControlName="nameType" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.prefix.errors }">
      <mat-option *ngFor="let obj of nameTypeSelection" [value]="obj.value"> {{ obj.viewValue }}</mat-option>
    </mat-select>
    <div *ngIf="submitted && f.nameType.errors" class="invalid-feedback">
            <div *ngIf="f.nameType.errors.required">Name Type is required</div>
          </div>
  </div>

  <div>
    <label>Prefix</label>
    <mat-select formControlName="prefix" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.prefix.errors }">
      <mat-option *ngFor="let obj of prefixes" [value]="obj.value"> {{ obj.viewValue }}</mat-option>
    </mat-select>
    <div *ngIf="submitted && f.prefix.errors" class="invalid-feedback">
            <div *ngIf="f.prefix.errors.required">Prefix is required</div>
          </div>
  </div>

  <div>
    <label>First Name</label>
    <input type="text" formControlName="firstName" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.firstName.errors }" />
    <div *ngIf="submitted && f.firstName.errors" class="invalid-feedback">
            <div *ngIf="f.firstName.errors.required">First Name is required</div>
          </div>
  </div>

  <div>
    <label>Middle Name (Optional)</label>
    <input type="text" formControlName="middleName" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.middleName.errors }" />
  </div>
  <div class="form-group">
    <label>Last Name</label>
    <input type="text" formControlName="lastName" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.lastName.errors }" />
    <div *ngIf="submitted && f.lastName.errors" class="invalid-feedback">
      <div *ngIf="f.lastName.errors.required">Last Name is required</div>
    </div>
  </div>

  <div>
    <label>Gender</label>
    <mat-select formControlName="gender" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.gender.errors }">
      <mat-option *ngFor="let obj of genders" [value]="obj.value"> {{ obj.viewValue }}</mat-option>
    </mat-select>
    <div *ngIf="submitted && f.gender.errors" class="invalid-feedback">
            <div *ngIf="f.gender.errors.required">Gender is required</div>
          </div>
  </div>
  <div>
    <input
      matInput
      [min]="minDate"
      [max]="maxDate"
      [matDatepicker]="picker"
      formControlName="dateOfBirth"
      placeholder="Choose Date of Birth"
    />
    <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
    <mat-datepicker #picker></mat-datepicker>
    <div *ngIf="submitted && f.dateOfBirth.errors" class="invalid-feedback">
            <div *ngIf="f.dateOfBirth.errors.required">Date of Birth is required</div>
          </div>
  </div>
  <div>
    <label>Citizenship</label>

    <mat-select formControlName="citizenship" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.prefix.errors }">
      <mat-option *ngFor="let obj of citizenships" [value]="obj.value"> {{ obj.viewValue }}</mat-option>
    </mat-select>
    <div *ngIf="submitted && f.citizenship.errors" class="invalid-feedback">
            <div *ngIf="f.citizenship.errors.required">Citizenship is required</div>
          </div>
  </div>
  <div class="form-group">
    <button>Save</button>
  </div>
</form>

I have attached a snapshot of my Screen. Why am I getting error in VS Code. enter image description here

Upvotes: 3

Views: 19795

Answers (4)

setayesh
setayesh

Reputation: 11

  // Form Variable for Ind Cust
  indCustregisterForm: FormGroup;
  submitted = false;
  
   ngOnInit() {
    this.indCustregisterForm = this.formBuilder.group({
      prefix: ['', Validators.required],
      nameType: ['', Validators.required],
      firstName: ['', Validators.required],
      middleName: [''],
      lastName: ['', Validators.required],
      gender: ['', Validators.required],
      dateOfBirth: ['', Validators.required],
      citizenship: ['', Validators.required]
    });
  }
  // convenience getter for easy access to form fields of Individual Customer Form
  get f() {
    return this.indCustregisterForm.controls;
  }
  
  onSubmit() {
    this.submitted = true;
    if (this.indCustregisterForm.valid) {
      console.log('Success')
    }

    // stop here if form is invalid
    if (this.indCustregisterForm.invalid) {
     console.log('Error')
      });
      return;
    }

  }
<!-- Individual Customer Form -->
<form [formGroup]="indCustregisterForm" (ngSubmit)="onSubmit()">
  <div>
    <label>Name Type</label>
    <mat-select formControlName="nameType" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.prefix.errors }">
      <mat-option *ngFor="let obj of nameTypeSelection" [value]="obj.value"> {{ obj.viewValue }}</mat-option>
    </mat-select>
    <div *ngIf="submitted && f.nameType.errors" class="invalid-feedback">
            <div *ngIf="f.nameType.errors.required">Name Type is required</div>
          </div>
  </div>

  <div>
    <label>Prefix</label>
    <mat-select formControlName="prefix" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.prefix.errors }">
      <mat-option *ngFor="let obj of prefixes" [value]="obj.value"> {{ obj.viewValue }}</mat-option>
    </mat-select>
    <div *ngIf="submitted && f.prefix.errors" class="invalid-feedback">
            <div *ngIf="f.prefix.errors.required">Prefix is required</div>
          </div>
  </div>

  <div>
    <label>First Name</label>
    <input type="text" formControlName="firstName" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.firstName.errors }" />
    <div *ngIf="submitted && f.firstName.errors" class="invalid-feedback">
            <div *ngIf="f.firstName.errors.required">First Name is required</div>
          </div>
  </div>

  <div>
    <label>Middle Name (Optional)</label>
    <input type="text" formControlName="middleName" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.middleName.errors }" />
  </div>
  <div class="form-group">
    <label>Last Name</label>
    <input type="text" formControlName="lastName" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.lastName.errors }" />
    <div *ngIf="submitted && f.lastName.errors" class="invalid-feedback">
      <div *ngIf="f.lastName.errors.required">Last Name is required</div>
    </div>
  </div>

  <div>
    <label>Gender</label>
    <mat-select formControlName="gender" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.gender.errors }">
      <mat-option *ngFor="let obj of genders" [value]="obj.value"> {{ obj.viewValue }}</mat-option>
    </mat-select>
    <div *ngIf="submitted && f.gender.errors" class="invalid-feedback">
            <div *ngIf="f.gender.errors.required">Gender is required</div>
          </div>
  </div>
  <div>
    <input
      matInput
      [min]="minDate"
      [max]="maxDate"
      [matDatepicker]="picker"
      formControlName="dateOfBirth"
      placeholder="Choose Date of Birth"
    />
    <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
    <mat-datepicker #picker></mat-datepicker>
    <div *ngIf="submitted && f.dateOfBirth.errors" class="invalid-feedback">
            <div *ngIf="f.dateOfBirth.errors.required">Date of Birth is required</div>
          </div>
  </div>
  <div>
    <label>Citizenship</label>

    <mat-select formControlName="citizenship" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.prefix.errors }">
      <mat-option *ngFor="let obj of citizenships" [value]="obj.value"> {{ obj.viewValue }}</mat-option>
    </mat-select>
    <div *ngIf="submitted && f.citizenship.errors" class="invalid-feedback">
            <div *ngIf="f.citizenship.errors.required">Citizenship is required</div>
          </div>
  </div>
  <div class="form-group">
    <button>Save</button>
  </div>
</form>

Upvotes: 1

harkesh kumar
harkesh kumar

Reputation: 883

Hi am not Sure what you trying to ask are you asking about error msg or you if you have error you not able to submit or save data

if You want to all Required data should fill in before save info then this work

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

<div class="form-group">
      <button [disabled]="!indCustregisterForm.valid" mat-flat-button color="primary">Submit</button>
  </div>

Error Msg

if you trying to show error message while you enter value in each field then its depend on what you using if you using Bootstrap or angular material they Both have different way to use error msg Bootstrap Examle

<input id="name" class="form-control"
      formControlName="name" required >

<div *ngIf="name.invalid && (name.dirty || name.touched)"
    class="alert alert-danger">

  <div *ngIf="name.errors.required">
    Name is required.
  </div>
  <div *ngIf="name.errors.minlength">
    Name must be at least 4 characters long.
  </div>
  <div *ngIf="name.errors.forbiddenName">
    Name cannot be Bob.
  </div>
</div>

Angular Material

Mat-error class to show error msg

Upvotes: 0

user11851731
user11851731

Reputation: 41

instead of writing

<div *ngIf = "f.nameType.errors.required"> 

you should write

<div *ngIf = "indCustregisterForm.controls['nameType']?.errors.required">

Upvotes: 4

Ritchie
Ritchie

Reputation: 562

This is a type safety issue. Your getter

get f() {
    return this.indCustregisterForm.controls;
  }

is returning a FormGroup type which doesn't know about nameType, prefix, etc... properties.

You need to use the built in get() method to retrieve controls. More info: https://angular.io/api/forms/AbstractControl#get

Upvotes: 1

Related Questions