Jakub Słowikowski
Jakub Słowikowski

Reputation: 1563

Angular Material Select - preselecting multiple values

In my case angular role is to receive JSON-entity from API and assign it's values to FormGroup. Everything works fine (FormGroup contains all expected values), but mat-select does not visually preselect given values.

All functionality described before is contained in onInit() method.

product-group-update.component.ts: full code: https://pastebin.com/hXLqBAcF

export class ProductGroupUpdateComponent implements OnInit {
  NO_PRODUCT: string = 'No product';
  editProductGroupForm: FormGroup;
  id: number;
  isFormSubmitted = false;
  availableProducts: Product[];
  toSelect: Product[];
 
  constructor(
    private formBuilder: FormBuilder,
    private productGroupService: ProductGroupService,
    private productService: ProductService,
    private router: Router,
    private activatedRoute: ActivatedRoute,
    private location: Location,
 
  ) {
  }
 
  ngOnInit(): void {
    this.editProductGroupForm = this.formBuilder.group({
      name: ['', [Validators.required, Validators.maxLength(100)]],
      description: ['', [Validators.required, Validators.maxLength(100)]],
      products: ['', []],
    });
 
    this.activatedRoute.paramMap.subscribe(params => {
      this.id = +params.get('id');
      this.productGroupService.getProductGroupById(this.id).subscribe(
        receivedProductGroup => {
          this.toSelect = receivedProductGroup.products;
          this.editProductGroupForm.setValue({
            name: receivedProductGroup.name,
            description: receivedProductGroup.description,
            products: receivedProductGroup.products,
          });
        }
      );
    });
    console.log(this.editProductGroupForm)
 
    this.productService.getAllProducts(new Page<Product>()).subscribe(response => {
      this.availableProducts = response.content;
    });
  }
 
  ...

}

product-group-update-component.html full code: https://pastebin.com/9GqyU2r2

<div class="col-md-12">
  <div class="card card-container">
 
    <form (ngSubmit)="submitForm()" [formGroup]="editProductGroupForm" class="new-obj-form" id="register-form">
      

      ...

 
      <mat-form-field appearance="fill" class="example-full-width">
        <mat-label>Products</mat-label>
        <mat-select formControlName="products" multiple [(value)]="toSelect">
          <mat-option [value]="NO_PRODUCT">{{NO_PRODUCT}}</mat-option>
          <mat-option *ngFor="let product of availableProducts" [value]="product">
            {{product.name}}
            <i><small>(ID: {{product.id}})</small></i>
          </mat-option>
        </mat-select>
      </mat-form-field>
 

    ...
 

    </form>
  </div>
</div>

As you can see: editProductGroupForm contains all the values: editProductGroupForm in console

And toSelect element (from which mat-select should take preselected values) too: toSelect in console

But mat-select does not preselect any values: mat-select

Other code:

export interface Product {
  id: number;
  name: string;
  description: string;
  price: number;
  groupId: number;
  sold: boolean;
}


import {Product} from "./product";

export interface ProductGroup {
  id: number;
  name: string;
  description: string;
  products: Product[];
}

Upvotes: 0

Views: 1291

Answers (1)

TotallyNewb
TotallyNewb

Reputation: 4790

Have in mind, that the Products in availableProducts and toSelect are different objects. So, when even though they have all the same properties, they are still different instances, meaning the comparison of the objects will return a false - that's why they're not selected.

You can fix it using two different approaches:

  1. mat-select supports the compareWith function - so you can override the default comparison and compare them, say, by Id. See official angular docs here for how it works. An example is avaialable in material docs as well.
  2. Use rxjs to combine both of your API calls and make sure that your toSelect are actual instances of the objects from the availableProducts table.

Upvotes: 1

Related Questions