gaetann
gaetann

Reputation: 101

Angular Reactive form submission in child components

I have set up a simple project to explain my issue. I have a main component defining a form with three fields. The third field is defined in a child component.

I simplify pass the formGroup to the child component to bind the values. It works all fine from a data binding perspective but when i click on submit for the form, i can see the validation working on fields defined in the parent component but the component in the child one is not turning red

Project example : https://stackblitz.com/edit/angular-74rac8 Click on submit

How can i tell the child the form has been submitted ? I thought it would be the case since i pass the same formGroup object

Upvotes: 2

Views: 1359

Answers (1)

yurzui
yurzui

Reputation: 214017

All Angular material form controls uses the same logic when updating error state:

@Injectable({providedIn: 'root'})
export class ErrorStateMatcher {
  isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
    return !!(control && control.invalid && (control.touched || (form && form.submitted)));
  }
}

It means that in order a control to be turned red it should has invalid status(works) but also it should be either touched or parent FormGroupDirective should be submitted.

You have two FormGroupDirective and only root directive((that is defined on <form [formGroup]="layerFormGroup" element) is submitted. Child FormGroupDirective(<div [formGroup]="formReference">) is not submitted therefore control is not turned red.

Note that if you touch child mat-select it will also be marked as invalid.

In order to solve it you can skip passing FormGroup to child component but rather tell Angular that you're going to use the same parent FormGroupDirective for your child component:

child.component.ts

import { FormGroupDirective, ControlContainer } from '@angular/forms';

@Component({
  selector: 'app-child',
  ...
  viewProviders: [
    {
      provide: ControlContainer,
      useExisting: FormGroupDirective
    }
  ]
}) 
export class ChildComponent implements OnInit  {

Forked Stackblitz

Upvotes: 3

Related Questions