0

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[];
}
1
  • 1
    In Angular, when using the subscribe you cannot ensure that the data arrives before the page is rendered, to check if this is the problem you could establish a resolver so that the rendering of the component waits for the data, or to try to include the mat-select a * ngIf = "this.toSelect" Commented Sep 16, 2020 at 14:10

1 Answer 1

1

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

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.