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>
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);