Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Material: mat-select default value when using reactive forms

I created a form using reactive forms and angular material mat-select which I use to create an object called "core". The core object has 2 properties: "name" and "owners". The "owners" property is an array of IUser objects.

The core object:

export interface ICore {
  id?: number;
  name: string;
  owners: IUser[];
}

The form:

<form [formGroup]="parentForm">
      <mat-form-field class="example-full-width">
        <input matInput formControlName="name" placeholder="Name">
      </mat-form-field>

      <mat-form-field class="example-full-width">
        <mat-label>Users</mat-label>
        <mat-select formControlName="owners" multiple>
          <mat-option *ngFor="let user of users" [value]="user"> {{ user.username }}</mat-option>
        </mat-select>
      </mat-form-field>
    </form>

The "users" variable is an array of all available users that can be selected.

 users: IUser[];

The form works great but now I want to use the same form to edit a core object and for that I need to display the core owners in the "owners" form control when the page is loaded.

Form creation:

  createForm() {
    this.coreForm = this.formBuilder.group({
      name: ['', [Validators.required]],
      owners: ['', [Validators.required]]
    });
  }

How I get the core:

getCore() {
    this.coreService.getCore(this.route.snapshot.params['id'])
      .subscribe(
        res => {
          this.core = res;
          this.updateForm();
        },
        err => this.toastr.error('Core has not been received!', 'Error!')
      );
  }

Form update(it works for the name property):

  updateForm() {
        this.coreForm.patchValue({
          name: this.core.name,
          owners: this.core.owners
        });
      }

But the owners list is not added. The strange thing is that if I update the form with the users it works:

  getUsers() {
    this.usersService.getUsers()
    .subscribe(
      res => {
        this.users = res;
        this.coreForm.patchValue({
          owners: res
        });
      },
      err => this.toastr.error('User could not be received!', 'Error!')
    );
  }

This way all the users are added as the default value. But for the core owners it's not working. Any idea what I do wrong here?

Thanks in advance!

like image 870
NicuVlad Avatar asked May 17 '19 13:05

NicuVlad


People also ask

How do you set mat selected value?

Angular Material Select is created using <mat-select> which is a form control for selecting a value from a set of options. To add elements to Select option, we need to use <mat-option> element and to bind value with <mat-option> , use value property of it.

How do you set the value of reactive form?

Setting or Updating of Reactive Forms Form Control values can be done using both patchValue and setValue. However, it might be better to use patchValue in some instances. patchValue does not require all controls to be specified within the parameters in order to update/set the value of your Form Controls.

How do you create a reactive form in angular materials?

Create Angular Reactive Form Import it in app. component. ts file and initialize an instance in constructor. Using the formBuilder instance, create a form group with form fields.

Which property is used in reactive forms?

Reactive forms provide access to information about a given control through properties and methods provided with each instance. These properties and methods of the underlying AbstractControl class are used to control form state and determine when to display messages when handling input validation.


1 Answers

You need to define the criteria based on which an object becomes considered as selected using the [compareWith] directive as follows:

<form [formGroup]="parentForm">
      <mat-form-field class="example-full-width">
        <input matInput formControlName="name" placeholder="Name">
      </mat-form-field>

      <mat-form-field class="example-full-width">
        <mat-label>Users</mat-label>
        <mat-select [compareWith]="compareFunction" formControlName="owners" multiple>
          <mat-option *ngFor="let user of users" [value]="user"> {{ user.username }}</mat-option>
        </mat-select>
      </mat-form-field>
</form>

and define your compareFunction:

compareFunction(o1: any, o2: any) {
 return (o1.name == o2.name && o1.id == o2.id);
}
like image 182
ala Avatar answered Sep 25 '22 10:09

ala