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'];
}
}
CodePudding user response:
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.
CodePudding user response:
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