How do I detect change to ngModel on a select tag (Angular 2)?

JavascriptAngular

Javascript Problem Overview


I am attempting to detect a change on ngModel in a <select> tag. In Angular 1.x, we might solve this with a $watch on ngModel, or by using ngChange, but I've yet to understand how to detect a change to ngModel in Angular 2.

Full Example: http://plnkr.co/edit/9c9oKH1tjDDb67zdKmr9?p=info

import {Component, View, Input, } from 'angular2/core';
import {FORM_DIRECTIVES} from 'angular2/common';

@Component({
	selector: 'my-dropdown'
})
@View({
	directives: [FORM_DIRECTIVES],
	template: `
		<select [ngModel]="selection" (ngModelChange)="onChange($event, selection)" >
			<option *ngFor="#option of options">{{option}}</option>
		</select>
		{{selection}}
	`
})
export class MyDropdown {
	@Input() options;

	selection = 'Dog';

	ngOnInit() {
    	console.log('These were the options passed in: ' + this.options);
  }
  
  onChange(event) {
    if (this.selection === event) return;
    this.selection = event;
    console.log(this.selection);
  }
	
}

As we can see, if we select a different value from the dropdown, our ngModel changes, and the interpolated expression in the view reflects this.

How do I get notified of this change in my class/controller?

Javascript Solutions


Solution 1 - Javascript

Update:

Separate the event and property bindings:

<select [ngModel]="selectedItem" (ngModelChange)="onChange($event)">

onChange(newValue) {
    console.log(newValue);
    this.selectedItem = newValue;  // don't forget to update the model here
    // ... do other stuff here ...
}

You could also use

<select [(ngModel)]="selectedItem" (ngModelChange)="onChange($event)">

and then you wouldn't have to update the model in the event handler, but I believe this causes two events to fire, so it is probably less efficient.


Old answer, before they fixed a bug in beta.1:

Create a local template variable and attach a (change) event:

<select [(ngModel)]="selectedItem" #item (change)="onChange(item.value)">

plunker

See also https://stackoverflow.com/questions/33700266/how-can-i-get-new-selection-in-select-in-angular-2

Solution 2 - Javascript

I have stumbled across this question and I will submit my answer that I used and worked pretty well. I had a search box that filtered and array of objects and on my search box I used the (ngModelChange)="onChange($event)"

in my .html

<input type="text" [(ngModel)]="searchText" (ngModelChange)="reSearch(newValue)" placeholder="Search">

then in my component.ts

reSearch(newValue: string) {
    //this.searchText would equal the new value
    //handle my filtering with the new value
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionluxView Question on Stackoverflow
Solution 1 - JavascriptMark RajcokView Answer on Stackoverflow
Solution 2 - JavascriptLogan HView Answer on Stackoverflow