[SOLVED] Angular – ngValue is not binding

Table of Contents

Issue

ngValue will not bind the value unless you keep the reference of the same list. Is it correct?

This will not work:

this.myForm.get('user').patchValue(this.currentUser);

This will work:

const findIndex = this.user.findIndex(
  (item) => item.id == this.currentUser.id
);
this.myForm.get('user').patchValue(this.user[findIndex]);

Also, I came to one more property compareWith that can be used to bind as well.

This will work if I use it with compareWith.

this.myForm.get('user').patchValue(this.currentUser);

Playground Link: https://stackblitz.com/edit/angular-ivy-a4zbhn?file=src%2Fapp%2Fapp.component.ts

Solution

You should use [compareWith] Input property binding to the <select> element so that Angular could bind the value to the <select> by your defined comparison logic.

.component.html

<select formControlName="user" [compareWith]="compare">
  <option *ngFor="let us of user" [ngValue]="us">{{ us.name }}</option>
</select>

.component.ts

compare(val1, val2) {
  return val1.id === val2.id;
}

Sample Solution on StackBlitz


Updated Remarks:

As Angular – SelectControlValueAccessor (Customizing option selection section) written,

Angular uses object identity to select option.

Without [compareWith], by default Angular will use object reference to select the option.

Hence your inference with the first method is correct and workable as long you are providing the object with the exact reference as the object(s) is existed in [ngValue].

const findIndex = this.user.findIndex(
    (item) => item.id == this.currentUser.id
);

this.myForm.get('user').patchValue(this.user[findIndex]);

References

Customizing option selection

Answered By – Yong Shun

Answer Checked By – Willingham (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *