I have trouble with filling the right values into input fields of a FormArray. Here is my html:
<div formArrayName="roles" *ngFor="let role of roles.controls; let i=index">
<div [formGroupName]="i">
<div class="form-group row">
<label class="col-md-2 col-form-label" attr.for="{{'roleNameId' + i}}">Role Name {{i+1}}</label>
<div class="col-md-6">
<input class="form-control"
attr.id="{{'roleNameId' + i}}"
type="text"
formControlName="roleName">
</div>
<label class="col-md-2 col-form-label" attr.for="{{'identifierId' + i}}">
<input
type="checkbox"
attr.id="{{'identifierId' + i}}"
formControlName="identifier"> identifier
</label>
<div class="col-md-2">
<button type="button" (click)="removeRole(i)" class="btn btn-danger oi oi-trash"></button>
</div>
</div>
</div>
</div>
So this html is being rendered x times depending on the number of roles i have. This works just fine and no errors are shown.
But here is the Problem: When i remove one Role which is not the last of the Array, the input fields filled with the right roles change.
Here are the roles:
When i remove role 2 for example, the form looks like this:
role2 was being removed correctly, but role3 disappeared and the last two roles have the name of the last role (role8)
Why this happens? When i look to the formArray where all roles are saved, the array has the correct values, here is the evidence:
why the correct values are not shown in the view? Thank you for your help
EDIT: Here is the relevant typescript code:
this.sourcesForm = this.fb.group({
sourceName: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(255)]],
sourceType: ['QUERY'],
dsl: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(255)]],
list: [''],
roles: this.fb.array([this.buildRole()]),
database: [''],
});
// save roles to temporary variable to map for the roles Formarray
let roles = [];
dslStatement.roles.forEach(role => {
let oneRole = {
roleName: role.name,
identifier: true
}
if (role.role === 'IDENTIFIER')
oneRole.identifier = true;
else
oneRole.identifier = false
roles.push(oneRole);
});
// convert the variable to FormGroups, then the FormGroups to one FormArray
// and at last set the FormArray to the roles of sourcesForm
const rolesFormGroups = roles.map(roles => this.fb.group(roles));
const rolesFormArray = this.fb.array(rolesFormGroups);
this.sourcesForm.setControl('roles', rolesFormArray);
buildRole(): FormGroup {
return this.fb.group({
roleName: '',
identifier: true
});
}
addRole() {
this.roles.push(this.buildRole());
}
removeRole(i: number) {
this.roles.removeAt(i);
console.log(this.roles.value);
console.log(this.roles.controls);
}
UPDATE I built a stackblitz attempting to demonstrating the issue here: https://stackblitz.com/edit/angular-dk-formarray
It uses Angular 5.0 and does NOT have the problem.
I was able to reproduce this with the app from my course referenced above (Angular 4):
After deleting the "a" row, I get this:
Notice that the "a" is gone, but now I have two "c"s instead of "b" and "c".
Interestingly, if I save and then come back to the page, it displays correctly with "b" and "c".
So it appeared to be a bug that was fixed in Angular 5.
I was able to find a "work around" that worked for me in Angular 4.x:
deleteTag(index: number): void {
this.tags.removeAt(index);
this.productForm.setControl('tags', this.fb.array(this.tags.value || []));
}
You may be able to do something similar to this (but I'm not sure your roles
are set up just like my tags
?)
But you are probably better off moving to Angular 5.