Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Make $debounce service part of angular !? #2690

@honzajde

Description

@honzajde

I am simply watching some objects on my scope that are changed as part of several digest cycles. After digesting them (changing their values via databinding) has finished, I want to save them to databse, but only ONCE and that is the point of the $debounce service.

From asking this question on SO, http://stackoverflow.com/questions/16278216/angularjs-save-changes-after-digest-has-finished, I didn't see that this common use-case that will once arise for anyone doing something more complex, is clearly solved.

So I came with this:

/**
 * Service function that helps to avoid multiple calls of a function (typically save()) during angular digest cycle.
 * $apply will be called after original function returns;
 *
 * Use it like this:
 *
 *  $scope.$watch('order', function(newOrder){
 *     $scope.orderRules.apply(newOrder); // changing properties on order
 *   }, true);
 *
 *  $scope.$watch('order.valid', function(newOrder){
 *     $scope.save(newOrder); //will be called multiple times while digested by angular
 *   });
 *
 *  $scope.save = debounce(function(order){
 *     // POST your order here ...$http....
 *     // debounce() will make sure save() will be called only once
 *   });
 */
define(['app'], function (app) {
    app.factory('debounce', ['$timeout', function ($timeout) {
        return function(fn, timeout, apply){ // debounce fn
            timeout = angular.isUndefined(timeout) ? 0 : timeout;
            apply = angular.isUndefined(apply) ? true : apply; // !!default is true! most suitable to my experience
            var nthCall = 0;
            return function(){ // intercepting fn
                var that = this;
                var argz = arguments;
                nthCall++;
                var later = (function(version){
                    return function(){
                        if (version === nthCall){
                            return fn.apply(that, argz);
                        }
                    };
                })(nthCall);
                return $timeout(later, timeout, apply);
            };
        };
    }]);
});

Question 1 to you: Do you see the need for such service?
Question 2 to you: Is this the optimal solution?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions