Reputation: 1651
I'm struggling getting the default selected option working and changing it based on a button click in my Angular 8 (Material) application.
I have created a stackblitz to demonstrate the same.
https://stackblitz.com/edit/angular-hbocgp
I want the region drop down to have default options selected as "North America" and on click of the button i want it to set it to some other options.
app.component.html
<mat-card>
<mat-form-field>
<mat-label>Region</mat-label>
<mat-select [(ngModel)]="regionSelected">
<mat-option *ngFor="let row of regionSelectionList" [value]="row">
{{row.name}}
</mat-option>
</mat-select>
</mat-form-field>
<button mat-raised-button color="primary" (click)="setRegion()">Set Region</button>
</mat-card>
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
regionSelected = { "itemId": 1, "name": "North America Seed" };
regionSelectionList = [
{"itemId":1, "name":"North America Seed"},
{"itemId":67505, "name":"1B: CU2 (North and Far West)"},
{"itemId":67504, "name":"1C: CU1 (Western Cornbelt)"},
{"itemId":67506, "name":"1K: CU3 (Eastern Cornbelt)"},
{"itemId":67503, "name":"1U: CU4 (Southern)"},
{"itemId":65143, "name":"5A: CU5 (Canada)"}
];
setRegion(){
console.log("Clicked");
this.regionSelected = {"itemId":67505, "name":"1B: CU2 (North and Far West)"};
}
}
Update:
Thanks for all the answers, but i ended up using below:
//default
this.regionSelected = this.regionSelectionList[this.regionSelectionList.findIndex(lst => lst.itemId == 1)];
// On button click
this.regionSelected = this.regionSelectionList[this.regionSelectionList.findIndex(lst => lst.itemId == 67505)];
Upvotes: 1
Views: 2709
Reputation: 977
The problem is referential equality. Even though in your sample code you're using all the same data, you're still creating different objects.
This happens because in your template you bind [value]="row"
, where row
is an object. If you'd bind to row.itemId
instead, and have regionSelected
equal to 1
from the start, and instead of assigning an object in the setRegion()
function, assign a necessary itemId
- it would work.
Like this:
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
regionSelectionList = [
{"itemId":1, "name":"North America Seed"},
{"itemId":67505, "name":"1B: CU2 (North and Far West)"},
{"itemId":67504, "name":"1C: CU1 (Western Cornbelt)"},
{"itemId":67506, "name":"1K: CU3 (Eastern Cornbelt)"},
{"itemId":67503, "name":"1U: CU4 (Southern)"},
{"itemId":65143, "name":"5A: CU5 (Canada)"}
];
regionSelected = 1;
setRegion(){
console.log("Clicked");
this.regionSelected = 67505;
}
}
OR, you could just use the same objects that's in your regionSelectionList
and let Angular compare them by reference:
export class AppComponent {
name = 'Angular';
regionSelectionList = [
{"itemId":1, "name":"North America Seed"},
{"itemId":67505, "name":"1B: CU2 (North and Far West)"},
{"itemId":67504, "name":"1C: CU1 (Western Cornbelt)"},
{"itemId":67506, "name":"1K: CU3 (Eastern Cornbelt)"},
{"itemId":67503, "name":"1U: CU4 (Southern)"},
{"itemId":65143, "name":"5A: CU5 (Canada)"}
];
regionSelected = this.regionSelectionList[0];
setRegion(){
console.log("Clicked");
this.regionSelected = this.regionSelectionList[2];
}
}
Upvotes: 2
Reputation: 5265
Try as follows.
regionSelected: any;
constructor() {
this.regionSelected = this.regionSelectionList[0];
}
Update
If you want to set the second region to select
on button click you can do it as below.
setRegion(){
this.regionSelected = this.regionSelectionList[1];
}
Upvotes: 1
Reputation: 960
Anser by @SudarshanaDayananda is actually correct, but just did not finish up, here is the working Stackblitz: https://angular-byx9ux.stackblitz.io
Why does your way not work? Your instantiation of
regionSelected = { "itemId": 1, "name": "North America Seed" };
might have the same variables, it is ,however, a different object compared to the one you have in your Array. In the select
you are setting the objects in the array, therefore the the set model will not be matched to your select options.
Another possibility might be to set your own compare function:
HTML:
<select [compareWith]="compareFn" ..>
TS:
compareFn(item1: any, item2: any) {
return item1 && item2 && item1.itemId === item2.itemId;
}
Upvotes: 1