Nathan Elg
Nathan Elg

Reputation: 187

How to use full objects in Angular reactive forms

I am updating some old angular forms and have an issue with setting the form to an entire instance of an object while also being able to set the initial value.

I have tried setting the [value]="option" to the entire object while having {{ option.$type }} but the initial value doesn't show up. I have also tried using [ngValue] but I get an error even when I import ReactiveFormModule

Current code:

<mat-form-field fxFlex="49">
    <mat-select placeholder="Type" formControlName="type" autocomplete="off" required>
        <mat-option *ngFor="let option of container$ | async" [value]="option.$type">{{ option.$type }}
        </mat-option>
    </mat-select>
</mat-form-field>

I would prefer to have the whole container object as the value so I am able to access the option.$id later, but

this.editContainerForm.controls['type'].setValue(this.containerContext.$containerTypeName );

stops working even if i set the form with the entire container object.

Upvotes: 0

Views: 186

Answers (1)

Muhammed Albarmavi
Muhammed Albarmavi

Reputation: 24424

Object are compared by reference in that case in order to use object as value must be the same reference

this mean

const a = {type$ : 'A'};
const a2 = {type$:'A'}; 

console.log(a === a2); // false 

if you try to use object both object has to be the same refrence

  const a = {type$ : 'A'};
  const a2 = a; 

  console.log(a === a2); // true

basic example

  form:FormGroup;
  container$;

  data = [
      {$type:'A'},
      {$type:'B'},
      {$type:'C'},
    ]
  constructor(fb:FormBuilder) {
    this.form = fb.group({
      type:this.data[1]
    })

    this.container$ = of(this.data)
  }

as you can see type has a value of the same refrence check the stackblitz demo 🔥🔥

Updated! ✨

you can provide [compareWith][2] a function to compare the option values with the selected values. The first argument is a value from an option. The second is a value from the selection. A boolean should be returned.

  compareWith(value , selectedValue ) {
    return value.$type === selectedValue.$type
  }

template

<mat-select placeholder="Type" formControlName="type" autocomplete="off" required [compareWith]="compareWith">
    <mat-option *ngFor="let option of container$ | async" [value]="option" >{{ option.$type }}
    </mat-option>
</mat-select>

stackblitz demo 🔥🔥

Upvotes: 1

Related Questions