0

I am trying to use component MatSelect from Angular Material, on the iteration part i am using an array of objects that comes from a function

Simple scenario that i got from Angular Material Website

html file

<h4>Basic mat-select</h4>
<mat-form-field appearance="fill">
  <mat-label>Favorite food</mat-label>
  <mat-select>
    <mat-option *ngFor="let food of foods" [value]="food.value">
      {{food.viewValue}}
    </mat-option>
  </mat-select>
</mat-form-field>

ts file

import {Component} from '@angular/core';

interface Food {
  value: string;
  viewValue: string;
}

/**
 * @title Basic select
 */
@Component({
  selector: 'select-overview-example',
  templateUrl: 'select-overview-example.html',
})
export class SelectOverviewExample {
  foods: Food[] = [
    {value: 'steak-0', viewValue: 'Steak'},
    {value: 'pizza-1', viewValue: 'Pizza'},
    {value: 'tacos-2', viewValue: 'Tacos'},
  ];
}

Simple scenario of what i am trying to do and it doesn't just work but also it freezes the web app, no error displayed on console

html file

<h4>Basic mat-select</h4>
<mat-form-field appearance="fill">
  <mat-label>Favorite food</mat-label>
  <mat-select>
    <mat-option *ngFor="let food of data()" [value]="food.value">
      {{food.viewValue}}
    </mat-option>
  </mat-select>
</mat-form-field>

ts file

import {Component} from '@angular/core';

interface Food {
  value: string;
  viewValue: string;
}

/**
 * @title Basic select
 */
@Component({
  selector: 'select-overview-example',
  templateUrl: 'select-overview-example.html',
})
export class SelectOverviewExample {
  foods: Food[] = [
    {value: 'steak-0', viewValue: 'Steak'},
    {value: 'pizza-1', viewValue: 'Pizza'},
    {value: 'tacos-2', viewValue: 'Tacos'}
  ];

  data(): Food[] {
    return [
      {value: 'steak-0', viewValue: 'Steak'},
      {value: 'pizza-1', viewValue: 'Pizza'},
      {value: 'tacos-2', viewValue: 'Tacos'}
    ];
  }
}

Extra info, this works fine if the return value of the function is an array of strings

html file

<h4>Basic mat-select</h4>
<mat-form-field appearance="fill">
  <mat-label>Favorite food</mat-label>
  <mat-select>
    <mat-option *ngFor="let food of data()" [value]="food">
      {{food}}
    </mat-option>
  </mat-select>
</mat-form-field>

ts file

import {Component} from '@angular/core';

interface Food {
  value: string;
  viewValue: string;
}

/**
 * @title Basic select
 */
@Component({
  selector: 'select-overview-example',
  templateUrl: 'select-overview-example.html',
})
export class SelectOverviewExample {
  foods: Food[] = [
    {value: 'steak-0', viewValue: 'Steak'},
    {value: 'pizza-1', viewValue: 'Pizza'},
    {value: 'tacos-2', viewValue: 'Tacos'},
  ];

  foods2 = ['Steak', 'Pizza', 'Tacos'];

  data(): string[] {
    return ['Steak', 'Pizza', 'Tacos'];
  }
}

2 Answers 2

1

The application got freeze because mat-option try to render all changes again. That's the way the first scenario is okay because the application knows nothing changes.

Solution use trackBy to tell ngFor for that do it use to compare changes.

<h4>Basic mat-select</h4>
<mat-form-field appearance="fill">
  <mat-label>Favorite food</mat-label>
  <mat-select>
    <mat-option *ngFor="let food of data(); trackBy: trackedValue" [value]="food.value">
      {{ food.viewValue }}
    </mat-option>
  </mat-select>
</mat-form-field>

Example: stackblitz

Sign up to request clarification or add additional context in comments.

Comments

0

The first scenario you have works for me because since I don't have mat-option component so no [value]="food.value". Maybe the problem is in the parameter that you are sending to the component. In fact, your third scenario maybe works because the parameter you are sending to the component is not food.value but food.

Hope this helps.

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.