Angular ngModelChange showing duplicate value from API json data

69 Views Asked by At

UPDATE: I have reproduced the error on Stackblitz for those who want to interact with the code. I have the following JSON data:

related_contacts: [
    {
        "id": 1,
        "relationship": "Brother",
        "date_created": "2023-07-24T22:40:16.497590+03:00",
        "date_modified": "2023-07-24T22:40:16.497590+03:00",
        "case": 170,
        "created_by": 3,
        "tenant": 2
    },
    {
        "id": 2,
        "relationship": "Wife",
        "date_created": "2023-07-24T22:40:16.507891+03:00",
        "date_modified": "2023-07-24T22:40:16.507891+03:00",
        "case": 170,
        "created_by": 3,
        "tenant": 2
    }
]

I'm trying to populate an input text field with the relationship value.

<div class="row py-3" *ngFor="let contact of case.related_contacts">
  <ng-container *ngIf="case.related_contacts.length > 1">
    <!--begin::Col-->
    <div class="col-lg-4">
      <!--begin::Label-->
      <label class="form-label text-dark fs-6">Relationship
      </label>
      <!--end::Label-->
      <!--begin::Input group-->
      <div class="form-floating mb-5">
        <input type="text" class="form-control" id="{{ contact.relationship }}" placeholder="Relationship" [ngModel]="contact.relationship" (ngModelChange)="testChange($event)" name="{{ contact.relationship }}" formControlName="relationship" autocomplete="off"/>
        <label for="state">Relationship</label>
      </div>
      <!--end::Input group-->
    </div>
    <!--end::Col-->
  </ng-container>
</div>

And im using the testChange function to see the value.

testChange($event: any) {
  console.log($event);
},

There is duplication in the fields.

Form Inputs

and the console log also shows the duplicate

Console Log

Any help on this would be appreciated.

1

There are 1 best solutions below

1
mbojko On

You're iterating twice: through editCaseForm.get('related_contacts')['controls'], and inside that loop through related_contacts instance property, not related in any way to the form. For added confusion, both ngFors use the same variable name:

<div class="collapse show" *ngFor="let contact of editCaseForm.get('related_contacts')['controls']; let i = index">
<!-- ... -->
    <div class="row py-3" *ngFor="let contact of related_contacts">

It isn't completely clear what exactly are you after, therefore I can't offer a complete solution.

EDIT: the outer contact variable is shadowed by the inner contact. And, using both ngModel and formControl you have two mechanisms fighting over control of the same input elements. The input is, on one hand, assigned ngModel from inner contact.relationship (so there should be two distinctive options), and on the other hand, is assigned to formControlName="relationship" of formGroup 0, therefore both inputs should represent the same value. Therefore, FormGroup and ngModel fight. To observe it, add

  ngOnInit() {
    this.editCaseForm.valueChanges.subscribe(console.log);
  }

The solution is still the same: pick either recipe, but not both.