18

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!

6
  • did you try adding [compareWith]="defineYourCompareFunction" to your mat-select ? Commented May 17, 2019 at 13:50
  • @ala, no. I didn't knew about this property Commented May 17, 2019 at 13:52
  • compareFunction(o1: any, o2: any) { if(o1.name == o2.name && o1.id == o2.id ) return true; else return false } Commented May 17, 2019 at 13:52
  • that's an example compare function, try it and let me know Commented May 17, 2019 at 13:53
  • From the documentation: /** 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. **/ Commented May 17, 2019 at 13:54

2 Answers 2

29

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);
}
Sign up to request clarification or add additional context in comments.

Comments

1

I agree with above answer I am posting this for users who have Angular mat-select and using reactive forms.

You can use the patchValue of Angular Reactive forms to have the default value selected

in your component in ngOnInit() or any place you want to have your dropdown selected value call patchValue function like below code:

  this.yourFrom.patchValue({
      CategoryID:1
    });

Comments

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.