19

Working with Angular2s forms and trying to figure out the process of handling events with selects. I have an object Heros that is stored in the options. What I want to do is that when I hero is selected, trigger an event to the parent component that will do something with the results. However, I can't find a concrete example of being able to receive an event when the selection has changed (ie a new hero in the list as been selected).

interface Hero {
  id: number;
  name: string;
}
@Component({
  selector: 'my-app',
  template:`
  <h1>{{title}}</h1>
  <form>
    <select>
        <option *ngFor="#hero of heros "
                [value]="hero">
            {{hero .name}}
        </option>
    </select>
  </form>
`
})
   export class AppComponent {
   @Input() heros:Observable<Hero>
   @Output("selectedHeroChange") selectedHeroChange:EventEmitter<any> = new EventEmitter

   onHeroChange(hero:Hero){
      this.selectedHeroChange._next(hero);
   }    
}

Thanks in advance!

cjr
  • 520
  • 2
  • 7
  • 22

3 Answers3

12

Execute code on select change and use an id property or index as value`:

<select (change)="onHeroChange($event)">
    <option *ngFor="#hero of heros; #i=index"
  [value]="hero.id">
      <!-- [value]="i" -->
        {{hero.name}}
    </option>
</select>

get the selected value from the event

onHeroChange(event:Event):void {
  Hero hero = heros.firstWhere(
      (Hero hero) => hero.id == (event.target as SelectElement).value);
  // Hero hero = heros[int.parse((event.target as SelectElement).value)];
  selectedHero = hero;
  selectedHeroChange.add(hero);
}

See also https://github.com/angular/angular/issues/4843#issuecomment-170147058

See also Binding select element to object in Angular 2

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • I was attempting to do this, but what is happening is that the [value]="hero" seems to be converted via toString instead of storing the actual object. To get this solution to work, I would have to have [value]="hero.id" and then I'd need to iterate through my list of for the onchange event and then return.... which seems like a gap (this functionality worked within KO) – cjr Jan 08 '16 at 23:07
  • 1
    For TS your function would look like this: `onheroChange(event: Event): void { ... }` – Wouter Vanherck Mar 30 '17 at 08:13
  • 1
    Thanks for the hint! Just a little more than a year but feels like ages ago :D – Günter Zöchbauer Mar 30 '17 at 08:16
  • That edit was quick! I've been trying to trigger an event when switching tabs in a md-tab-group. It does seem to have a selectChange-event but I don't know how to define it. Your solution was worth a shot, thanks. – Wouter Vanherck Mar 30 '17 at 08:18
  • That seems promissing but I'm not quite sure how to implement that. I'm fairly new to Angular 2 and I've not used @Output yet. Could we take this to chat or should I ask a new StackOverflow question? – Wouter Vanherck Mar 30 '17 at 08:29
  • 1
    You shouldn't need to implement an output, the `` has that already. You should just need to add an expression that you want to have executed on tab-change where I put `...` – Günter Zöchbauer Mar 30 '17 at 08:30
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/139465/discussion-between-wouter-vanherck-and-gunter-zochbauer). – Wouter Vanherck Mar 30 '17 at 08:33
  • 1
    Correction to my (deleted) comment above: What about – Günter Zöchbauer Mar 30 '17 at 08:36
6

Seem there is a gap in ng2 that select cannot handle objects. Here is a work round for now.

How to use select/option/NgFor on an array of objects in Angular2

Community
  • 1
  • 1
cjr
  • 520
  • 2
  • 7
  • 22
2

You get the object from a select by using

[ngValue]="hero" 

instead of

[value]="hero".
Robin
  • 21
  • 1