Basically I have two arrays, and I would like to store their values at the same time using a *ngFor
, I did something like this just to show what I would expect:
I think your issue is here:
addAlternativeField() {
this.alternativeFields.push(this.fbuilder.control(''));
this.alternativeFieldsValues.push(this.fbuilder.control(''));
}
You are patching the arrays in direct reference to this. Isn't it supposed to be
this.form.get('alternativeFields').push(this.fbuilder.control(''))
Or do you have an additional getter?
I believe your mistake is having 2 arrays of controls instead of one array of groups:
alternativeFieldsAndValues: this.fbuilder.array([]),
and then:
get alternativeFieldsAndValues() {
return this.form.get('alternativeFieldsAndValues') as FormArray;
}
addAlternativeFieldAndValue() {
this.alternativeFieldsAndValues.push(this.fbuilder.group({
titulo: '',
conteudo: ''
}));
}
removeAlternativeFieldAndValue(index: any) {
this.alternativeFieldsAndValues.removeAt(index);
}
make sure to refactor all names properly then do this:
<div formArrayName="alternativeFieldsAndValues" *ngFor="let field of alternativeFieldsAndValues.controls; let i = index">
<div [formGroupName]="i">
<mat-form-field appearance="standard" class="fullSize">
<mat-label>Titulo</mat-label>
<input formControlName="titulo" type="text" matInput autocomplete="off"
placeholder="Titulo">
</mat-form-field>
<mat-form-field appearance="standard" class="fullSize">
<mat-label>Conteúdo</mat-label>
<input formControlName="conteudo" type="text" matInput autocomplete="off"
placeholder="Conteúdo deste campo">
</mat-form-field>
</div>
</div>
that being said, you could accomplish exactly what you asked like this:
<div *ngFor="let field of alternativeFields.controls; let i = index">
<mat-form-field formArrayName="alternativeFields" appearance="standard" class="fullSize">
<mat-label>Titulo</mat-label>
<input [formControlName]="i" type="text" matInput autocomplete="off"
placeholder="Titulo">
</mat-form-field>
<mat-form-field formArrayName="alternativeFieldsValues" appearance="standard" class="fullSize">
<mat-label>Conteúdo</mat-label>
<input [formControlName]="i" type="text" matInput autocomplete="off"
placeholder="Conteúdo deste campo">
</mat-form-field>
</div>
but this does require the two lists are ALWAYS of the same length.
Matheus, a formArray can be a FormArray of FormControls or a FormArrays of FormGroup (*)
form=new FormGroup({
arrayOfControls=new FormArray([])
})
pushArrayOfControls()
{
this.form.get('arrayOfControls').push(new FormControl())
}
//or using FormBuilder
this.form = this.fb.group(
{
arrayOfControls: this.fb.array([])
}
)
pushArrayOfControls() {
(this.form.get('arrayOfControls') as FormArray).push(
this.fb.control('')
)
}
A formArray of FormGroup:
form=new FormGroup({
arrayOfFormGroup=new FormArray([])
})
pushArrayOfFormGroup()
{
this.form.get('arrayOfControls').push(
new FormGroup({
prop1:new FormControl()
prop2:new FormControl()
}))
}
//or using FormBuilder
form=this.fb.group({
arrayOfFormGroup=this.fb.array([])
})
pushArrayOfFormGroup()
{
this.form.get('arrayOfControls').push(this.fb.group({
prop1:'',
prop2:''
})
}
One store an array of values ['a','b','c'], the other store an array of object [{prop1:'a',prop2:'aa'},{prop1:'a',prop2:'aa'}]
To manage it's use different ways. The clasic for a FormArray of controls is
<div [formGroup]="form">
<div formArrayName="arrayOfControls">
<div *ngFor="let control of form.get('arrayOfControls').controls;let i=index">
<!---use [formControlName]="i"-->
<input [formControlName]="i"/>
</div>
</div>
</div>
But remember, our formArray is a formArray of control, so we can do something like
<div [formGroup]="form">
<div formArrayName="arrayOfControls">
<div *ngFor="let control of form.get('arrayOfControls').controls;">
<!---use [formControl]="control", the variable of the *ngFor-->
<input [formControl]="control"/>
</div>
</div>
</div>
And we can make something so "bizarro" like
<div [formGroup]="form">
<div formArrayName="arrayOfControls">
<div *ngFor="let control of form.get('arrayOfControls').controls;let i=index">
<input [formControl]="form.get('arrayOfControls').at(i)"/>
</div>
</div>
</div>
A formArray of formGroup, we can the way clasic
<div [formGroup]="form">
<div formArrayName="arrayOfFormGroup">
<!--see that we use [formGroupName]-->
<div *ngFor="let control of form.get('arrayOfFormGroup').controls;
let i=index" [formGroupName]="i">
<input formControlName="prop1"/>
<input formControlName="prop2"/>
</div>
</div>
</div>
Well, nobody say that we can not do, remember that is a formArray of controls, so, for.get('arrayOfGroup').controls is a FormGroup
<div [formGroup]="form">
<div formArrayName="arrayOfControls">
<!--here I used "formGroup"-->
<div *ngFor="let group of form.get('arrayOfControls').controls"
[formGroup]="group">
<input formControlName="prop1"/>
<input formControlName="prop2"/>
</div>
</div>
</div>
even something so "bizarro"
<div [formGroup]="form">
<div formArrayName="arrayOfControls">
<div *ngFor="let group of form.get('arrayOfControls').controls;let i=index" >
<!--I used directily [formControl]-->
<input [formControl]="form.get('arrayOfControls').at(i).get('prop1')"/>
<input [formControl]="form.get('arrayOfControls').at(i).get('prop2')"/>
</div>
</div>
</div>
Well, now, the question is: What do you want? a formArray of FormGroup or an formArray of FormControls, what way of referered to the FormControls do you wants, using formControl, using formControlName, using formGroup?
NOTE: it's usefull use a getter to referered to our formArray
get myArray()
{
return this.form.get('arrayOfControls') as FormArray
}
and replace in the .html this "ugly" form.get(....)
(*)Really a FormArray don't need create into a formGroup, they "lives" outside