Here's an example:
constructor(public fb: FormBuilder) {
this.form = this.fb.group({
foobars: this.fb.array([fb.group({ foo: null, bar: null })]),
baz: null
});
const formValues = {
foobars: [
{ foo: 1, bar: 'one'}
{ foo: 2, bar: 'two'}
],
baz: 'baz'
};
this.form.reset(formValues);
}
addFoobar() {
this.form.controls.foobars.push(this.fb.group({ foo: null, bar: null }))
}
And a template:
<div>
<div *ngFor="let foobar of form.controls.foobars.controls">
foo: <input [formControl]="foobar.controls.foo" type="number">
bar: <input [formControl]="foobar.controls.bar">
</div>
baz: {{ form.controls.baz.value }}
<button (click)="addFoobar()">Add foobar</button>
</div>
The form is supposed to have variable amount of foo
/bar
control pairs. which are stored then as foobars
array in database and retrieved as a plain object (formValues
is static in this example, but in reality it is not).
The problem is that reset
doesn't create nested controls in foobars
form array automatically, while I would expect that it will.
How can form value be set here with reset
? Is creating foobar
item manually as fb.group({ foo: ..., bar: ... })])
the only correct way to add/set nested controls?
you can try to restructure your constructor like:
foobars
form array is created by FormBuilder with empty arrayfoobars
form array is filled with initial entries usingformValues.foobars.map()
function which executesaddFoobar()
for each iteration.this.form.reset(formValues)
@DeborahK, I disagree with you about
here is this function: https://github.com/angular/angular/blob/c59c390cdcd825cca67a422bc8738f7cd9ad42c5/packages/forms/src/model.ts#L1221.
On updated plunker I added the button 'Set value for form array' which is enabled when there are exactly 3 array items, clicking the button will update form array with
setValue()
function:updated plunker: http://plnkr.co/edit/XALYC8hUxkY0hIJrGLHx?p=preview