Indraraj26
Indraraj26

Reputation: 1966

Angular - ngValue is not binding

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

Upvotes: 1

Views: 1900

Answers (1)

Yong Shun
Yong Shun

Reputation: 51260

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

Upvotes: 3

Related Questions