Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular add FormGroup to FormGroup

I have a parent component which is the main FormGroup. Inside this <my-parent></my-parent> component I have a child component, <my-child></my-child>.

The child component has a *ngIf="some-conditional", and inside the child component, I have a quick fill button which basically does patchValue on a couple of the child FormGroup controls.

It successfully adds the child FormGroup to parent FormGroup, but the values of the child inside of the parent are always empty.

I've tried to add the controls two ways(both unsuccessful), with a setter inside the parent component, and by emitting from inside the child component and reassigning the new value to the parent FormGroup.

Here's a stackblitz with a demo of what im trying to do. Thanks in advance!

// PARENT COMPONENT

import {
  Component,
  ViewChild
} from '@angular/core';
import {
  FormBuilder,
  FormGroup,
  Validators
} from '@angular/forms';

import {
  ChildComponent
} from './child.component';

@Component({
  selector: 'my-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./app.component.scss']
})
export class ParentComponent {
  isChildFormSet = false;
  showChildComponent = false;
  exampleParentForm: FormGroup;

  // @ViewChild(ChildComponent)
  // set userForm(childForm: ChildComponent) {
  //   if (childForm && !this.isChildFormSet) {
  //     this.isChildFormSet = true;
  //     setTimeout(() => {
  //       this.exampleParentForm.addControl('child', new FormGroup(childForm.exampleChildForm.controls));
  //     });
  //   }
  // }

  constructor(private fb: FormBuilder) {
    this.exampleParentForm = this.fb.group({
      parent: ['', Validators.required]
    })
  }

  submitForm(): void {
    console.log(this.exampleParentForm)
  }

  addChildComponent(): void {
    this.showChildComponent = true;
  }

  onChange(form) {
    // reset the form value to the newly emitted form group value.
    this.exampleParentForm = form;
  }
}


// CHILD COMPONENT

import {
  Component,
  OnInit,
  Input,
  Output,
  EventEmitter
} from '@angular/core';
import {
  FormBuilder,
  FormGroup,
  Validators
} from '@angular/forms';

@Component({
  selector: 'my-child',
  templateUrl: './child.component.html',
  styleUrls: ['./app.component.scss']
})
export class ChildComponent implements OnInit {
  exampleChildForm: FormGroup;

  @Input() formData: FormGroup;
  @Output() onFormGroupChange: EventEmitter < FormGroup > = new EventEmitter < FormGroup > ();


  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.exampleChildForm = this.fb.group({
      child: ['', Validators.required]
    });

    this.addGroupToParent();
  }

  fillWithText() {
    this.exampleChildForm.patchValue({
      child: 'This is an exmple.'
    });
  }

  clearText(): void {
    this.exampleChildForm.get('child').setValue('');
  }

  private addGroupToParent(): void {
    this.formData.addControl('child', new FormGroup(this.exampleChildForm.controls));
    this.onFormGroupChange.emit(this.formData);
  }
}
<!-- PARENT COMPONENT -->

<div class="parent-container">
  <form [formGroup]="exampleParentForm" (submit)="submitForm()" novalidate>
    <div class="col-3">
      <input class="effect-1" type="text" placeholder="Parent Input" formControlName="parent" />
      <span class="focus-border"></span>
    </div>
    <my-child *ngIf="showChildComponent" [formData]="exampleParentForm" (onFormGroupChange)="onChange($event)">
    </my-child>
    <div>
      <button class="button parent" type="submit">Log Form Value</button>
    </div>
  </form>
  <button class="button small" type="button" (click)="addChildComponent()">Add Child Component</button>
</div>

<!-- CHILD COMPONENT -->

<div class="child-container" [formGroup]="exampleChildForm">
  <div class="col-3">
    <input class="effect-1" type="text" placeholder="Child Input" formControlName="child">
    <span class="focus-border"></span>
  </div>
  <div>
    <button class="button child" type="button" (click)="fillWithText()">Patch Value</button>
  </div>
</div>
like image 854
alphapilgrim Avatar asked Feb 21 '19 16:02

alphapilgrim


People also ask

How do I add a FormControl to a FormGroup?

How to add a FormControl to a FormGroup. To add, update, or remove controls in FormGroup , use the following commands: addControl() adds a control and updates its value and validity. removeControl() removes a control.

What is difference between FormBuilder and FormControl?

In Angular, a reactive form is a FormGroup that is made up of FormControls. The FormBuilder is the class that is used to create both FormGroups and FormControls.

Can FormArray contains FormGroup?

FormArray is a variant of FormGroup. The key difference is that its data gets serialized as an array (as opposed to being serialized as an object in case of FormGroup). This might be especially useful when you don't know how many controls will be present within the group, like dynamic forms.


1 Answers

Instead of adding new FormGroup instance to the parent group simply add the child form group itself.

So

this.formData.addControl('child', new FormGroup(this.exampleChildForm.controls));

becomes

this.formData.addControl('child', this.exampleChildForm);

Forked Stackblitz

like image 61
yurzui Avatar answered Sep 18 '22 20:09

yurzui