Search code examples
javascriptangularjsangular-resource

How to send angular form data that has changed?


I have a couple of forms that interact with a backend service to persist the data.

I am wondering if there's a standard angular way to detect what properties of the model has changed and send them only in the POST? Currently all is sent event when not changed.


Solution

  • As per the question, there can be two situations.

    1. Once user has filled the fields and click on SAVE button which will finally send a PATCH request for saving//updating values.

    2. As user changes the values, a request needs to be made.

    For the 1.

    You can keep a track of what's get changed by maintaining a hashmap. Use ng-modal directive for all user input fields. Let's assume there's two input fields i. username and password.

    <input type="text" ng-modal="username" />
    <input type="password" ng-modal="password" />
    

    In your controller

    $scope.userInfo = {
      user: $scope.username,
      pass: $scope.password
    };
    

    Now if anything gets changed, it will be reflected in your views and models via a two-way binding.

    So, now you can compare the old and new values and accordingly send the desired ones.

    For the 2.

    Use Angular's watchCollection.

    scope.$watchCollection('[username, password]', function () {
      // send a request
    });
    

    EDIT

    One can use debounce method for the second approach

    // Returns a function, that, as long as it continues to be invoked, will not
    // be triggered. The function will be called after it stops being called for
    // N milliseconds. If `immediate` is passed, trigger the function on the
    // leading edge, instead of the trailing.
    _.debounce = function(func, wait, immediate) {
      var timeout, args, context, timestamp, result;
    
      var later = function() {
        var last = _.now() - timestamp;
    
        if (last < wait && last >= 0) {
          timeout = setTimeout(later, wait - last);
        } else {
          timeout = null;
          if (!immediate) {
            result = func.apply(context, args);
            if (!timeout) context = args = null;
          }
        }
      };
    
      return function() {
        context = this;
        args = arguments;
        timestamp = _.now();
        var callNow = immediate && !timeout;
        if (!timeout) timeout = setTimeout(later, wait);
        if (callNow) {
          result = func.apply(context, args);
          context = args = null;
        }
    
        return result;
      };
    };
    

    Source: https://github.com/jashkenas/underscore/blob/master/underscore.js