0

I've an object which contains 100 keys, value pairs.

$scope.obj = {
  key1: value1,
  key1: value1,
  .
  .
  .
  key100: value100
}

I have 100 inputs

<form>
   <input value="obj.key1" ng-model="obj.key1" />
   <input value="obj.key2" ng-model="obj.key2" />
   <input value="obj.key3" ng-model="obj.key3" />
   .
   .
   .
   <input value="obj.key100" ng-model="obj.key100" />
   <button ng-click="submit> </button>
</form>

When I sumbit the data will send to server. Some time I'll change values and sometimes not. If I change a value in one input I want that key,value from object. So that I can send server call with that data not to send entire data.

lin
  • 17,956
  • 4
  • 59
  • 83
Mr.Pandya
  • 1,899
  • 1
  • 13
  • 24

5 Answers5

1

I would achieve this by using the default ngForm directives like $dirty and a "save state" object of your original input values. This is a easy solution to achieve what you want. ngForm itself does not provide the original values so you have to create a "save object" and compare them manually.

View

<div ng-controller="MyCtrl">
  <form name="myForm" ng-submit="submit()">
    <input type="text" name="key1" ng-model="obj.key1"><br />
    <input type="text" name="key2" ng-model="obj.key2"><br />
    <input type="text" name="key3" ng-model="obj.key3">
    <input type="submit" id="submit" value="Submit" />
  </form>
</div>

AngularJS application

var myApp = angular.module('myApp',[]);

myApp.controller('MyCtrl', function ($scope) {

    $scope.obj = {
      key1: 'test 1',
      key2: 'test 2',
      key3: 'test 3',
    }

    var originalValues = angular.copy($scope.obj);

    $scope.submit = function () {

      var paramsChanged = {};

      angular.forEach($scope.obj, function (value, key) {
          if ($scope.myForm[key].$dirty && originalValues[key] !== value) {
            paramsChanged[key] = value;
          }
      });

      console.log(paramsChanged);
    }
});

> demo fiddle

lin
  • 17,956
  • 4
  • 59
  • 83
  • If i have nested Objects. Your solution will not work and it is not working when i change more than one value. it always returning last edited only – Mr.Pandya Mar 16 '18 at 10:41
  • @Mr.Pandya also with nested objects it will work with a small code change. But if you got nested object, why don't you add them to your question? There is no information about "nested" object inside your question. How should we help you with that if we don't know about your full requirements? In your question you told us that you just have a `key,value` object. – lin Mar 16 '18 at 10:44
  • @Mr.Pandya I modified the solution. There was a small error in it. Now it will collect all changed values not even the last one. – lin Mar 16 '18 at 11:01
  • @lin -- How is this different from my solution, except that you're checking `$dirty` flag? – 31piy Mar 16 '18 at 11:38
0

Have a copy of the variable and just before sending it to the server, compare the model object with the copied variable using a compare function like the following:

// At the time of initialization
$scope.obj = [ ... ];
var copiedObj = angular.copy($scope.obj);

// At the time of submit
var changed = {};

Object.keys(copiedObj).forEach(key => {
  if(copiedObj[key] !== $scope.obj[key]) {
    changed[key] = $scope.obj[key];
  }
});

// Submit `changed` to the server

Assuming copiedObj is the copy of original $scope.obj, changed will contain the keys which are actually changed. So you can send changed to the server.

31piy
  • 23,323
  • 6
  • 47
  • 67
0

You can use $watch to watch for specific changes in $scope.

$scope.$watch('obj.key1', function(newValue, oldValue) {
  console.log('Key1 was updated from' + oldValue + ' to ' + newValue');
});
Jim Wright
  • 5,905
  • 1
  • 15
  • 34
0

You can do this way have a ng-change bind to your HTML and whenever the ng-change happens for a particular Element write a code to push into an array and send that array to the server. A sample Code

    <input value="obj.key100" ng-model="obj.key100" ng-change="selectedValue(obj.keyx)" />

Angular Code

 $scope.tempValues=[];
 $scope.selectedValue = function(x) {
    $scope.tempValues.push(x);
 }
Kannan T
  • 1,639
  • 5
  • 18
  • 29
  • What happens when a key is changed and reset again to the original value? – 31piy Mar 16 '18 at 10:20
  • Then in that case we need to compare with existing value only by having a IF condition OP doesn't want to iterate each elements so i had to go for this logic – Kannan T Mar 16 '18 at 10:21
  • @Kannan. Initially my input value is 'kannan'. I removed 'n'. Then I added 'n'. FInally result is 'Kannan'. This time your condition fails. – Mr.Pandya Mar 16 '18 at 10:23
  • Yes @Mr.Pandya but you don't want to iterate nor use $watch then what other options is there? – Kannan T Mar 16 '18 at 10:24
0

You can use ng-change to detect any changes, as well as a (key, value) syntax in ng-repeat to list your inputs. Here is a demo:

var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
  $scope.obj = {
    "key1": "value1",
    "key2": "value2",
    "key3": "value3"
  }

  var toSend = [];
  $scope.select = function(key) {
    var s = {};
    s[key] = $scope.obj[key]
    toSend.push(s); // or just the value: $scope.obj[key]
  }

  $scope.submit = function() {
    console.log(toSend)
    $scope.sent = toSend;
  }

});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>

<div ng-app="myApp" ng-controller="myCtrl">

  <form ng-submit="submit()">
    <div ng-repeat="(key,value) in obj">
      <input ng-change="select(key)" ng-model="value" /><br>
    </div>
    <button type="submit">Send</button>
  </form>

  <pre>{{sent | json}}</pre>

</div>
Aleksey Solovey
  • 4,153
  • 3
  • 15
  • 34