Reputation: 3614
I have a problem using a reactive form in an Angular app. I managed to isolate the problem in a Plunkr.
https://plnkr.co/edit/KiTHcaaZZA6kwDI0sfeR?p=preview
What I have is a form with an ArrayForm section where I can add rows with a button. Every one of these rows has many input fields, and a few of them display the result of other fields. For example, in my plunkr I have a MAX and a MIN button, which are numbers, and when both of them have a value, I need to update the value of another field, called TOTAL.
So this is the html template:
<form [formGroup]="form">
<div>
<input type="text" formControlName="client" placeholder="client">
</div>
<button type="button" (click)="addPublisher()">Add Publisher</button>
<div formArrayName="publishers">
<div *ngFor="let item of publishers; let i = index;">
<div [formGroupName]="i">
<input type="number" formControlName="max" placeholder="max">
<input type="number" formControlName="min" placeholder="min">
<input type="text" formControlName="total" placeholder="total">
</div>
</div>
</div>
</form>
And this is the ts that matters. I'm subscribing to changes in the publishers, and updating the row only if the change is other than a row being added or deleted.
ngOnInit() {
(this.form.get('publishers') as FormArray).valueChanges
.map((publishers: any[]) => {
if (this.totalPublishers === publishers.length) {
publishers.forEach((publisher, index) => {
console.log(`update publishers ${index}`);
this.updatePublisher((this.form.get('publishers') as FormArray).get([index]) as FormGroup);
});
} else {
console.log(`update total from ${this.totalPublishers} to ${publishers.length}`);
this.totalPublishers = publishers.length;
}
})
.subscribe();
}
And to update the value, I do this
private updatePublisher(publisher: FormGroup) {
this.updateTotals(publisher);
}
private updateTotals(publisher: FormGroup) {
const max = publisher.get('max').value;
const min = publisher.get('min').value;
if (max && min) {
console.log(max, min);
const total = max - min;
publisher.get('total').setValue(total);
}
}
If I execute this, when I update the first field (max) it checks the value, and as min does not exist yet, nothing happens. Correct. Then when I edit the second value (min), this updateTotals is executed a zillion times, total is calculated at the end and updated in the field, but then if I try to edit those fields again and update the values nothing happens.
Any idea why this is happening?
Thanks.
Upvotes: 0
Views: 370
Reputation: 214067
When you call setValue
valueChange
event is fired within updateValueAndValidity
. One option should help you
publisher.get('total').setValue(total, { emitEvent: false });
this way your valueChange
handler won't be executed infinitely.
Upvotes: 1