1
votes

I have an Angular form that is composed of multiple FormGroup sub-forms and should span multiple components. It is initialized on and submitted from parent component, with each child getting a FormGroup they are responsible for. Controls are made with Angular Material.

The problem is, when I submit the form, validations don't work. They work just fine if the submit button is moved inside the child components, so it is in the same component as a form group I'm validating, but that's not what I'm trying to achieve.

Code examples are below, with dummy names.

Parent template:

<form [formGroup]="mainForm" (ngSubmit)="submitForm()">
    <button mat-button mat-raised-button color="primary" type="submit">Save</button>
    <first-child [firstChildGroup]="mainForm.get('firstChildGroup')"></first-child>
    <second-child [secondChildGroup]="mainForm.get('secondChildGroup')"></second-child>
</form>

Parent TS:

export class ParentComponent implements OnInit {
    mainForm: FormGroup;
    constructor(private fb: FormBuilder) {}

    ngOnInit(): void {
        this.mainForm = this.fb.group({
            firstChildGroup: this.fb.group({
                one: ['', [Validators.required]] // and other controls with other validators
            }),
            secondChildGroup: this.fb.group({...})
        });    
    }
}

Child template:

<div [formGroup]="firstChildGroup">
    <mat-form-field appearance="fill">
        <mat-label>First child group <strong class="text-danger">*</strong></mat-label>
        <input matInput formControlName="one">
        <mat-error>
            Required
        </mat-error>
    </mat-form-field>
</div>

Child TS:

export class FirstChildComponent {
    @Input() firstChildGroup: FormGroup;
}

So, to recap: ParentComponent passes intialized FormGroup elements to several child components, but the validation won't work when submit button is on parent. Which it has to be.

Any solution to this? All suggestions are also welcome.

1

1 Answers

0
votes

Since we using standalone FormGroup directive inside child component when we call onSubmit from parent it's not getting propagated to child component.

We can overcome this issue by creating sub form using FormGroupDirective instead of passing formControl to child component.

<form #fgd="ngForm" [formGroup]="mainForm" (ngSubmit)="submitForm()">
    <button (click)="fgd.onSubmit(null)" mat-button mat-raised-button color="primary" type="submit">Save</button>
    <first-child></first-child>
    <second-child></second-child>
</form>

child.component.ts

@Component({
  selector: 'app-first-child',
  templateUrl: './first-child.component.html',
  styleUrls: ['./first-child.component.css'],
  viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }]
})
export class FirstChildComponent implements OnInit {
   firstChildGroup: FormGroup;

  constructor(private parentForm: FormGroupDirective) { }

  ngOnInit() {
    this.firstChildGroup = this.parentForm.form;
  }

}

child.component.html

<div  formGroupName="firstChildGroup">
    <mat-form-field appearance="fill">
        <mat-label>First child group <strong class="text-danger">*</strong></mat-label>
        <input matInput formControlName="one">
        <mat-error>
            Required
        </mat-error>
    </mat-form-field>  
</div> 

Working Example