0

I am creating a select element, and want to set an object as the default value when the application starts. In my example I have a list of animals, and a FormControl used in an HTML template. I tried adding an object (not a reference to an object) directly to the formControl like this:

animalControl = new FormControl({name:'Dog', sound: 'Woof!'}, [Validators.required]); // this does not work

This does not work. However, referencing an object from the actual list works, like this:

this.animalControl.setValue(this.animals[1]); // this works

Is there another way of setting a value to the formControl without having to find the correct reference, only passing an object to it instead?

Working example: https://stackblitz.com/edit/angular-object-default-select?file=app/select-hint-error-example.ts

TS:

 export class SelectHintErrorExample {
  animalControl = new FormControl({name:'Dog', sound: 'Woof!'}, [Validators.required]); // this does not work

  animals = [
    {name: 'Dog', sound: 'Woof!'},
    {name: 'Cat', sound: 'Meow!'},
    {name: 'Cow', sound: 'Moo!'},
    {name: 'Fox', sound: 'Wa-pa-pa-pa-pa-pa-pow!'},
  ];
  constructor(){
    // this.animalControl.setValue(this.animals[1]); // this works
  }

}

HTML:

<mat-form-field>
  <mat-select placeholder="Favorite animal" [formControl]="animalControl" required>
    <mat-option>--</mat-option>
    <mat-option *ngFor="let animal of animals" [value]="animal">
      {{animal.name}}
    </mat-option>
  </mat-select>
  <mat-error *ngIf="animalControl.hasError('required')">Please choose an animal</mat-error>
  <mat-hint>{{animalControl.value?.sound}}</mat-hint>
</mat-form-field>

2 Answers 2

2

If you don't want to create a reference, you can use compareWith in your select, just like on any other select tag:

<mat-select [compareWith]="compareAnimals" ...

and TS:

compareAnimals(a1: any, a2: any): boolean {
  return a1 && a2 ? a1.name === a2.name : a1 === a2;
}

Your StackBlitz: https://stackblitz.com/edit/angular-object-default-select-ervu6r?file=app%2Fselect-hint-error-example.ts

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your answer. I will give it a try next week. I am just concerned about efficiency. Will the ‘compareAnimals’ method run after each change cycle? In that case it might be better to find the reference once after all.
0

Use FormBuilder https://angular.io/guide/reactive-forms#introduction-to-formbuilder. You must decided that you want to use a FormArray or not

//If a only animal
createForm(data:any)
{
  this.animalcontrol=this.fb.group({
      name: [data.name?data.name:'',Validators.Required],
      sound:[data.sound=data.sound:'']
    });
}

if you want use a formArray, check too Angular 5 populate data with FormArray

1 Comment

Thank you for your answer. This approach means that my animalcontrol must be of type FormGroup, I want it to be of type FormControl. Also, if I have an object with a lot more properties, would I still need to copy all of them? Isn't it an approach to pass the object itself, instead of copying it?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.