Search code examples
angularjsangularjs-model

Angularjs debounce for multiple events not working


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.


Solution

  • 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.