raju
raju

Reputation: 6936

Using mat-error in nested reactive form group

I have a nested FormGroup

this.outerForm= this.formBuilder.group({
  firstFormGroup: this.formBuilder.group({
    nserNumber: ['', Validators.required]
  }),
  ...
});

I'm trying the following:

<fieldset formGroupName="firstFormGroup">
        <ng-template matStepLabel>Enter NSER</ng-template>
        <div class="formRow">
          <div class="col-custom-col-50">
            <mat-form-field>
              <input matInput placeholder="NSER number" id='nserNumber' formControlName="nserNumber">
              <mat-error *ngIf="outerForm.controls.firstFormGroup.controls.nserNumber.required">Required</mat-error>
            </mat-form-field>
            <pre>{{outerForm.controls.firstFormGroup.controls.nserNumber | json}}</pre> 
          </div>
        </div>

But this mat-error is not working. Please help

Upvotes: 5

Views: 14053

Answers (4)

Sunit S
Sunit S

Reputation: 75

In my case, I did this:

in the component file:

this.address = this.formBuilder.group({
  main: new FormControl('', Validators.required),
  city: new FormControl('', Validators.required),
  state: new FormControl('', Validators.required),
  postal: new FormControl('', Validators.required)
})

ngOnInit(): void {
this.profileForm = this.formBuilder.group({
  fullName: new FormControl('', Validators.required),
  email: new FormControl('', [Validators.required, Validators.email]),
  telephone: new FormControl('', [Validators.required]),
  address: this.address
})

}

in the HTML:

<form
        [formGroup]="profileForm"
        (ngSubmit)="updateProfile()"
>
<form formGroupName="address">
                    <mat-form-field
                        appearance="outline"
                        class="example-full-width"
                    >
                        <mat-label>Address</mat-label>
                        <textarea
                            rows="15"
                            matInput
                            formControlName="main"
                        ></textarea>
                        <mat-error *ngIf="address.controls['main'].hasError('required')">Address is required</mat-error>
                    </mat-form-field>
                    <table class="example-full-width">
                        <tbody>
                            <tr>
                                <td>
                                    <mat-form-field
                                        appearance="outline"
                                        class="example-full-width"
                                    >
                                        <mat-label>City</mat-label>
                                        <input
                                            matInput
                                            placeholder="Ex. Bangalore"
                                            formControlName="city"
                                        >
                                        <mat-error *ngIf="address.controls['city'].hasError('required')">City is required</mat-error>
                                    </mat-form-field>
                                </td>
                                <td>
                                    <mat-form-field
                                        appearance="outline"
                                        class="example-full-width"
                                    >
                                        <mat-label>State</mat-label>
                                        <input
                                            matInput
                                            placeholder="Ex. Karnataka"
                                            formControlName="state"
                                        >
                                        <mat-error *ngIf="address.controls['state'].hasError('required')">State is required</mat-error>
                                    </mat-form-field>
                                </td>
                                <td>
                                    <mat-form-field
                                        appearance="outline"
                                        class="example-full-width"
                                    >
                                        <mat-label>Postal Code</mat-label>
                                        <input
                                            matInput
                                            #postalCode
                                            maxlength="5"
                                            placeholder="Ex. 94105"
                                            value
                                            maxlength="6"
                                            minlength="6"
                                            formControlName="postal"
                                        >
                                        <mat-error *ngIf="address.controls['postal'].hasError('required')">Postal Code is required</mat-error>
                                    </mat-form-field>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </form>
</form>

Working fine for me, here is a screenshot:

enter image description here

Upvotes: 0

Baz
Baz

Reputation: 155

You can access the desired nested FormControl directly using dot expression like this

<mat-error *ngIf="outerForm.get('firstFormGroup.nserNumber').errors.required">
<!-- or -->
<mat-error *ngIf="outerForm.get('firstFormGroup.nserNumber').hasError('required')">

The accepted answer also contains dirty/touched checks which are unnecessary when using mat-error component, Material library handles this by itself.

Upvotes: 1

sivy
sivy

Reputation: 451

Instead to do

<mat-error *ngIf="outerForm.controls.firstFormGroup.controls.nserNumber.required">

do this:

  <mat-error *ngIf="outerForm.controls.firstFormGroup.get('nserNumber').hasError('required') && (outerForm.controls.firstFormGroup.get('nserNumber').dirty || outerForm.controls.firstFormGroup.get('nserNumber').touched)">

Upvotes: 9

Nithya Rajan
Nithya Rajan

Reputation: 4884

In your component.ts, you should create a getter method to get the controls of your firstFormGroup.

get firstFormGroupControls() {
  return this.outerForm.get('firstFormGroup')['controls'];
}

In your component.html, you can access the firstFormGroupControls like below:

 <mat-error *ngIf="firstFormGroupControls.nserNumber.required">Required</mat-error>

Upvotes: 2

Related Questions