2

I was looking at the Angular documentation for handling forms and found a very useful example for capturing the update in any field/control with a delay. Following is the sample code provided by Angularjs:

<input type="text" ng-model="user.name" ng-model-options="{ debounce: 250 }" /><br />

It works fine. But they mentioned that debounce can be used with multiple events and provided another example like:

<input type="text" ng-model="user.name" ng-model-options="{ updateOn: 'default blur', debounce: { default: 500, blur: 0 } }" /><br />

The problem with this example is that it always delay the updation whether you leave the field/control or not. Whereas in this case it should immediately update the model when user leave the field/control as debounce is 0 in case of blur.

Here is link for running example in Plunker.

Can anyone explain this behavior.

Haider
  • 1,488
  • 2
  • 15
  • 29

2 Answers2

8

I believe you fell victim to Javascript's type conversion, specifically that 0 is false. Checkout the unminified source for Angular 1.3.0-beta7, line 18305:

var debounceDelay = ctrl.$options && (isObject(ctrl.$options.debounce)
    ? (ctrl.$options.debounce[trigger] || ctrl.$options.debounce['default'] || 0)
    : ctrl.$options.debounce) || 0;

Soif you have specified options.debounce it will try to set the debounceDelay first to options.debounce.blur, as you expected. But since this is 0 (false), it proceeds with the ... || ... to ctrl.$options.debounce['default'], which is non-zero (true) and sets this value!

As a workaround, you can either specify the exact name of the event that triggers default (is it keyup?), or specify a small, but non-zero value for your delay, e.g. 1:

debounce: { default: 500, blur: 1 }

I think this should be filed as bug to Angular.

Nikos Paraskevopoulos
  • 39,514
  • 12
  • 85
  • 90
  • 2
    I am trying to do the same thing, but using mouseup. I can't seem to make it work. Apparently the 'default' and 'mouseup' are incompatible. The only way I can fix it is to remove the default and break it down into the various events, such as... ng-model-options="{ debounce : { cut: 0, paste: 0, keypress: 500, mouseup : 0, blur : 0 } }" – John Henckel Aug 18 '15 at 21:11
0

In my case it was necessary to specify updateOn along with the debounce object, like so:

<textarea
    ng-model="$ctrl.notes"
    ng-model-options="{ updateOn: 'default blur', debounce: { 'default': 500, 'blur': 0 } }">
</textarea>
Konrad Garus
  • 53,145
  • 43
  • 157
  • 230