1

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)];
0

3 Answers 3

2

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

Comments

1

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;
}

Comments

1

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];
}

StackBlitz

3 Comments

default option works, but how can i set up on click of a button? your blitz doesn't show that piece.
you do not need to set it manually. try console.log(this.regionSelected) in setRegion() function and you will see selected region is assigned to the regionSelected variable. see my stackblitz again
well may be i was not clear on my requirements. I need to set default to NA (id = 1) and i would want to change it to option (id = 67505) on click of a button.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.