1

I am new to Angular 2 and I've recently been trying the two-way binding. I have the following code:

template.html

<select [(ngModel)]="val" (change)="onChanged()">
   <option>1</option>
   <option>2</option>
   <option>1</option>
</select>

component.ts

..//other code definitions here
export class MyComponent{
  val: number = 1; //edited this

  onChanged(){
    console.log(this.val);
  }
}

The problem is when the selected value on the dropdown changes, the value outputted on the console is still the previous value. It only updates after I select again another value, but the printed value was still the previously selected value. So it's like delayed by one selection.

Hope anyone can help.

Thanks.

Jed
  • 1,054
  • 1
  • 15
  • 34

2 Answers2

2

The val value will only be updated on the next Angular2 change detection cycle. To use the latest value in onChanged method, consume $event value like this:

<select [(ngModel)]="val" (change)="onChanged($event)">

In MyComponent:

onChanged(newVal){
  console.log(newVal);
}
Harry Ninh
  • 16,288
  • 5
  • 60
  • 54
  • Doesn't it defeat the purpose of 2 way binding? I'll have to clutter my functions with parameters where I already have a model bound to the view. – Jed Oct 28 '16 at 02:56
  • IMO it does not. 2-way data binding still being reserved (as in the value in parent component is updated eventually). What you need here is another concern: How to perform some actions on that particular event. Cluttering 2 different concerns into 1 is the easiest way to get headaches. – Harry Ninh Oct 28 '16 at 03:22
2

When you use two-way binding - [(ngModel)], always use (ngModelChange) instead of (change):

<select [(ngModel)]="val" (ngModelChange)="onChanged()">
   <option>1</option>
   <option>2</option>
   <option>1</option>
</select>

Here's working Plunker.

Stefan Svrkota
  • 48,787
  • 9
  • 98
  • 87
  • Yes but the thing is the onChanged() function is being called twice when I use the ngModelChange. – Jed Oct 28 '16 at 02:54
  • I've edited my post, i've missed something on the val declaration. – Jed Oct 28 '16 at 02:58
  • @Jed It still gets called once on every change, check out the Plunker I provided again. – Stefan Svrkota Oct 28 '16 at 07:01
  • 1
    I'm not really sure what's going on with my code, but the code inside my onChange is actually fetching from server so I just created a boolean variable to check if the promise hasn't returned yet this way it doesn't execute twice. Im not sure if it's a clean workaround but it's working. Thank you for your help. – Jed Oct 29 '16 at 00:43