3
votes

I have a company class, it has an headquarter's address field. The address is an interface, it has an another object, country, which is an another interface. In my database I store all the countries. I have a view for editing a selected company, there I can set or change the headquarter's address and I created a mat-select for the countries:

<mat-select [(ngModel)]="company.headquarter.country">
    <mat-option *ngFor="let country of companyService.countries" [value]="country">
        {{country.name}}
    </mat-option>
</mat-select>

This code save the selected country to the headquarter's country field, but if I want to edit the same company the mat-select doesn't display the actual value. how can I solve this problem?

Edited:

If I change the ngModel to company.headquarter.country.id and the [value] to country.id, then it works fine, but to store the country's code or name I have to write a method, which will find the country by the id in the companyService.countries array and set this country to the company.headquarter.country's field. So it is not a good solution.

2
Is it ChangeDetection issue ? Your main component is in OnPush detection strategy ? if yes, please check angular.io/api/core/ChangeDetectorRefYanis-git

2 Answers

8
votes

This code save the selected country to the headquarter's country field, but if I want to edit the same company the mat-select doesn't display the actual value. how can I solve this problem?

The problem is when you mat-select compares two object, their references can be different. Use compare function to compare your object by some mark like id.

To customize the default option comparison algorithm, supports compareWith input. compareWith takes a function which has two arguments: option1 and option2. If compareWith is given, Angular selects option by the return value of the function.

Template:

 <mat-form-field>
              <mat-select [(value)]="contract.company"
                          panelClass="example-panel-dark-blue"
                          [compareWith]="helper.compareById">

                <mat-option *ngFor="let cust of customers"
                            [value]="cust"> {{cust.title}}
                </mat-option>
              </mat-select>
  </mat-form-field>

Code:

 compareById(f1: Common.Item, f2: Common.Item): boolean {
     return f1 && f2 && f1.id === f2.id;
 }

Official Doc

0
votes

Change [(ngModel)] to [(value)].

<mat-select [(value)]="company.headquarter.country"> 
  <mat-option *ngFor="let country of companyService.countries" [value]="country"> {{country.name}}
   </mat-option>
</mat-select>