Monday 6 June 2016

Watch the change of a value in a Variable or Array or property in a array using Angular JS

In Angular js we have lot of things to make notify the data changes, because in MVVM or MVC pattern, view have to update automatically whenever there is a change in the data. so we take a scenario that if there is a change in the variable or array collection we have to re render the view based on some logic, Then now we see how to handle that kind of scenario in code.

Angular have $watch in the Scope where we can monitor the changes of the variable value. In $watch  we have three kind of different behaviours. value changes, new value add changes, deep value changes.

Value changes: 
****************
In this where we can get notify for variable whenever the value is changed, that includes a variables and array.


mainApp.controller('TestController', ['$scope','$timeout',function ($scope,$timeout) {

    $scope.Exams = [{ id: 1, marks: 80, name: 'ramu' },
{ id: 2, marks: 94, name: 'shiny' },
{ id: 3, marks: 56, name: 'raj' }];

    $scope.FirstRank = $scope.Exams[1];

}]);



consider the above controller where we have two kind of variable one is object and other is array.
Now we want to get notify whenever there is a change in the value i.e like

    $scope.FirstRank = { id: 3, marks: 56, name: 'rajesh' }
     $scope.Exams =    [{ id: 4, marks: 80, name: 'ram' },
  { id: 5, marks: 94, name: 'Sis' },
   { id: 6, marks: 56, name: 'FGH' }];

so i.e here the whole value for a variable is changed ,for this we have to create a watch variable with two ways ,

 First way is add a variable as string as a first parameter , second parameter as callback . Now this string is converted to a function internally.

     
  $scope.$watch('FirstRank'function (newval, oldval) {      

        /* any logic you want to do */
        $timeout(function () { $scope.$apply(); }, 0);


    });


    $scope.$watch('Exams'function (newval, oldval) {

        /* any logic you want to do */
        $timeout(function () { $scope.$apply(); }, 0);


    });

Second way is adding a function as a first parameter, callback as second parameter.

    $scope.$watch(function () { return $scope.FirstRank; }, function (newval, oldval) {
       
        /* any logic you want to do */
        $timeout(function () { $scope.$apply(); }, 0);


    });

Both are doing the job, but the way of declaration is same, If there is a scenario where we want to get the notify when new item is added in collection then above $watch is failed to notify. For this we have to specify the another one i.e


New value add changes
**********************

Ex:      $scope.Exams.push({ id: 3, marks: 56, name: 'raju' });

For  this we have to make another way.


    $scope.$watchCollection('Exams'function (newval,oldval) {

        /* any logic you want to do */
        $timeout(function () { $scope.$apply(); }, 0);


    });



From the code you can unde'rstand the change in the collection can be found out $watchCollection, but we cant found out using $watch.

Deep Value Changes
*******************
If we want to get the notify for a property value change of a object inside a collection, then we have to monitor the each and every property change for this we have to pass a additional flag to the $watchCollection , as true that will take care remaining things.

    Ex:  $scope.Exams[0].Id = 10;

    $scope.$watchCollection('Exams'function (newval, oldval) {

        /* any logic you want to do */
        $timeout(function () { $scope.$apply(); }, 0);


    }, true);








mainApp.controller('TestController', ['$scope','$timeout',function ($scope,$timeout) {

    $scope.Exams = [{ id: 1, marks: 80, name: 'ramu' }, { id: 2, marks: 94, name: 'shiny' }, { id: 3, marks: 56, name: 'raj' }];

    $scope.FirstRank = $scope.Exams[1];


    $scope.$watch('FirstRank'function (newval, oldval) {      

        /* any logic you want to do */
        $timeout(function () { $scope.$apply(); }, 0);

    });

    $scope.$watch(function () { return $scope.FirstRank; }, function (newval, oldval) {
       
        /* any logic you want to do */
        $timeout(function () { $scope.$apply(); }, 0);

    });

    $scope.$watch('Exams'function (newval, oldval) {

        /* any logic you want to do */
        $timeout(function () { $scope.$apply(); }, 0);


    });

    $scope.$watchCollection('Exams'function (newval,oldval) {

        /* any logic you want to do */
        $timeout(function () { $scope.$apply(); }, 0);


    });

    $scope.$watchCollection('Exams'function (newval, oldval) {

        /* any logic you want to do */
        $timeout(function () { $scope.$apply(); }, 0);

    }, true);


}]);


From this post you can learn the whole thing about the $watch a variable value changes and deep changes

No comments:

Post a Comment