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>
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With