39

I am trying to build a drop down with a few values.

However, on selecting a value, I want to make an API call that takes an id.

In my component.ts, I have an array of values:

values = [
  { id: 3432, name: "Recent" },
  { id: 3442, name: "Most Popular" },
  { id: 3352, name: "Rating" }
];

In my template, I am using that array as follows:

<select>
  <option *ngFor="let v of values" [value]="v">  
    {{v.name}}
  </option>
</select>

However, on picking a value from the drop down, how can I access the id property? I want to use that in my function getPhotosByType(id).

Thanks

user1354934
  • 8,139
  • 15
  • 50
  • 80

6 Answers6

65

My answer is little late but simple; but may help someone in future; I did experiment with angular versions such as 4.4.3, 5.1+, 6.x, 7.x, 8.x, 9.x, 10.x, 11.x, 12.x, 13.x, 14.x using $event (latest at the moment)

Template:

<select (change)="onChange($event)">
    <option *ngFor="let v of values" [value]="v.id">{{v.name}}</option>
</select>

TS

export class MyComponent {
  public onChange(event): void {  // event will give you full breif of action
    const newVal = event.target.value;
    console.log(newVal);
  }
}
mumair
  • 2,768
  • 30
  • 39
  • Worked for me. Thanks. – D_Edet Apr 03 '18 at 10:58
  • change works whenever the value of select is changed, what if we want to track whenever any value is selected, even if it is the current value? @mumair – Mayank Singh Fartiyal May 29 '18 at 11:12
  • @MayankSingh above snippet will work great when ever value is changed by user. If I get you correctly you want to set default value OR you want to compare the selected value is equal to current (predefined) value. can you please further explain? – mumair May 29 '18 at 14:57
  • I need to add columns to table on select of any value from the dropdown, but a column can be added more than once, by this case I can add columns alternatively but not consecutively. So when i select a dropdown item 2 times is a row, on change will not occur @mumair – Mayank Singh Fartiyal May 30 '18 at 05:37
  • I wish I could edit the closing tag – MortimerCat Mar 14 '19 at 10:15
28

You need to use an Angular form directive on the select. You can do that with ngModel. For example

@Component({
  selector: 'my-app',
  template: `
    <h2>Select demo</h2>
    <select [(ngModel)]="selectedCity" (ngModelChange)="onChange($event)" >
      <option *ngFor="let c of cities" [ngValue]="c"> {{c.name}} </option>
    </select>
  `
})
class App {
  cities = [{'name': 'SF'}, {'name': 'NYC'}, {'name': 'Buffalo'}];
  selectedCity = this.cities[1];

  onChange(city) {
    alert(city.name);
  }
}

The (ngModelChange) event listener emits events when the selected value changes. This is where you can hookup your callback.

Note you will need to make sure you have imported the FormsModule into the application.

Here is a Plunker

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • 1
    if your selectedCity is undefined in the initial state, you define a disabled option that show "select a city" by simply doing: `` – manubot Apr 30 '17 at 10:58
4
values_of_objArray = [
  { id: 3432, name: "Recent" },
  { id: 3442, name: "Most Popular" },
  { id: 3352, name: "Rating" }
];

private ValueId : number = 0 // this will be used for multi access like 
                             // update, deleting the obj with id.
private selectedObj : any;

private selectedValueObj(id: any) {
  this.ValueId = (id.srcElement || id.target).value;
  for (let i = 0; i < this.values_of_objArray.length; i++) {
    if (this.values_of_objArray[i].id == this.ValueId) {
      this.selectedObj = this.values_of_objArray[i];
    }
  }
}

Now play with this.selectedObj which has the selected obj from the view.

HTML:

<select name="values_of_obj" class="form-control" [(ngModel)]="ValueId"  
        (change)="selectedValueObj($event)" required>

  <option *ngFor="let Value of values_of_objArray"
          [value]="Value.id">{{Value.name}}</option>    
</select>
zgue
  • 3,793
  • 9
  • 34
  • 39
Rinold
  • 343
  • 1
  • 2
  • 12
2

Another solution would be,you can get the object itself as value if you are not mentioning it's id as value: Note: [value] and [ngValue] both works here.

<select (change)="your_method(values[$event.target.selectedIndex])">
  <option *ngFor="let v of values" [value]="v" >  
    {{v.name}}
  </option>
</select>

In ts:

your_method(v:any){
  //access values here as needed. 
  // v.id or v.name
}

Note: If you are using reactive form and you want to catch selected value on form Submit, you should use [ngValue] directive instead of [value] in above scanerio

Example:

  <select (change)="your_method(values[$event.target.selectedIndex])" formControlName="form_control_name">
      <option *ngFor="let v of values" [ngValue]="v" >  
        {{v.name}}
      </option>
    </select>

In ts:

form_submit_method(){
        let v : any = this.form_group_name.value.form_control_name;  
    }
Nabin Kumar Khatiwada
  • 1,546
  • 18
  • 19
1

Template/HTML File (component.ts)

<select>
 <option *ngFor="let v of values" [value]="v" (ngModelChange)="onChange($event)">  
    {{v.name}}
  </option>
</select>

Typescript File (component.ts)

values = [
  { id: 3432, name: "Recent" },
  { id: 3442, name: "Most Popular" },
  { id: 3352, name: "Rating" }
];

onChange(cityEvent){
    console.log(cityEvent); // It will display the select city data
}

(ngModelChange) is the @Output of the ngModel directive. It fires when the model changes. You cannot use this event without the ngModel directive

VIKAS KOHLI
  • 8,164
  • 4
  • 50
  • 61
-1
<select [(ngModel)]="selectedcarrera" (change)="mostrardatos()" class="form-control" name="carreras">
    <option *ngFor="let x of carreras" [ngValue]="x"> {{x.nombre}} </option>
</select>

In ts

mostrardatos(){

}
Rob
  • 26,989
  • 16
  • 82
  • 98
JFB
  • 21
  • 1