Angular 5, reactive forms, nested components, error messages

Hello,

I am creating a project with a big form that i would like to break on different components.
I used an @Input in the child form component and pass it from the father by using [formGroup]=“parentFormGroup” in the child like bellow

<div class="form-group" [formGroup]="parentFormGroup">
  <div class="form-group" formGroupName="design">
    <div class="form-group" formGroupName="level1">
      <input class="form-control" formControlName="name"/>

The form is defined in the parent

this.all_form = this.fb.group({ // <-- the parent FormGroup
      design: this.fb.group({
        level1: this.fb.group({
          name: ['', Validators.required]
        })
      })
    })

Now on the child template i want to print an error message but nothing works. I tried

<span *ngIf="parentFormGroup.controls.name.errors.required">Required Field</span>

and

<span *ngIf="parentFormGroup.design.level1.controls.name.errors.required">Required Field</span>

and

parentFormGroup.design.level1.controls.get('name').hasError('required')

They give error

TypeError: _co.parentFormGroup.design is undefined

Can you share live code (in something like stackblitz or plunkr)?

Trying to describe something like this is really hard without the actual code.

Here is the code, not working cause the structure is wrong and i have not imported the libs but still all the files are there.

https://plnkr.co/93ZR64PXATPCKpHEaeZN
If i have missed something tell me.

First off, nested form groups in the same component get very nasty very fast. If you can break down your formGroups into sub-components, so each components is concerned with only 1 level of the formGroup.
Or you can use a middle step where you get the formValues and map it to the full object format, instead of trying to warp the formGroup into the object you want in the end.

Or you can just simplify your form entirely.

Regardless the format to show/hide errors is:

formGroup.controls['controlName'].hasError('required')

so the template format is:

<span *ngIf="formGroup.controls[controlName].hasError('required')">

So for your example I would try

<span *ngIf="parentFormGroup.controls['design'].controls['level1'].controls['name'].hasError('required')">
</span>

As you can see the syntax starts getting pretty nasty.

Here’s an example stackBlitz I created to check on the syntax. (Use stackBlitz not plunker, its faster more stable)
https://stackblitz.com/edit/angular-zsupuy

1 Like