javascriptangularjsangularjs-serviceangularjs-watch

AngularJs $watchGroup - which expression in the group was last changed?


Using $watchGroup, how can I determine which expression in the group was changed

    $scope.$watchGroup(['dec','bin','oct','hex'], function(newValues, oldValues, scope) {
       last_changed = ??? //return which exp was changed in this run...
       if(last_changed=='dec') //then something
       if(last_changed=='bin') //then something
       if(last_changed=='oct') //then something
       if(last_changed=='hex') //then something
    });


Edit 1:-
--->the problem is i can't unbind the n_vals from the newValues.

var n_vals = [];
 $scope.$watchGroup(['dec','bin','oct','hex'], function(newValues, oldValues, scope) {
  last_updated = changed_one(newValues,n_vals); //last_updated EXP
    n_vals = newValues;
 });

Solution:-

n_vals = angular.copy(newValues);

look the following link:
Deep copying objects in angular?


Solution

  • Angular offers $watchGroup (since 1.3).

    Basically, it returns the scope variable oldValue and newValue in the manner how we put it in watchGroup.

    Use the index of the scope variable to get its respective newVal and oldVal like below.

    To get newValues of respective scope variables:

    newValue[0] // returns new value of dec
    newValue[1] // returns new value of bin
    newValue[2] // returns new value of oct
    newValue[3] // returns new value of hex
    

    To get oldValues of respective scope variables:

    oldValue[0] // returns old value of dec
    oldValue[1] // returns old value of bin
    oldValue[2] // returns old value of oct
    oldValue[3] // returns old value of hex
    
    $scope.$watchGroup(['dec','bin','oct','hex'], function(newValues, oldValues, scope) {
        console.log(newValues[index]); //put index value as 0(dec), 1(bin), 2(oct) or 3(hex)
        console.log(oldValues[index]); //put index value as 0(dec), 1(bin), 2(oct) or 3(hex)
    });
    

    NOTE:
    Below logic is considering that only one value will change at a time.

    Edit 1

    To catch which variable was updated last, you can try below code.

    var arrayOfValues = ['dec', 'bin', 'oct', 'hex'];
    $scope.$watchGroup(arrayOfValues, function(newValues, oldValues, scope) {
        let last_changed;
    
        var chanedIndex = newValues.findIndex(function(val, key){
            return val !== oldValues[key];
        });
    
        last_changed = arrayOfValues[chanedIndex];
    
        // above logic could simply avoid the below conditional logic (refer 
        // comment above in front of if condition)
        if (angular.isDefined(last_changed)) {
            // your logic will come here as per your question
            switch(last_changed){
               case 'dec':
                   doSomething();
               case 'bin':
                   doSomething();
               case 'oct':
                   doSomething();
               case 'hex':
                   doSomething();
            }
        }
    });
    

    Edit 2:

    I have minified the code and made the

    var arrayOfValues = ['dec', 'bin', 'oct', 'hex'];
    // generic method which will tell you which variable has been updated
    $scope.checkWhichVariableHasUpdated = fucntion(watchGroupList, newValuesObj, oldValuesObj) {
        let _lastUpdatedValue;
        angular.forEach(watchGroupList, function(value, index) {
            if (newValuesObj[index] != oldValuesObj[index])
                _lastUpdatedValue = value;
        });
        return _lastUpdatedValue;
    };
    
    $scope.mySwitchFunction = function(changedVariable) {
        switch (changedVariable) {
            case 'dec':
                doSomething();
                break;
            case 'bin':
                doSomething();
                break;
            case 'oct':
                doSomething();
                break;
            case 'hex':
                doSomething();
                break;
        }
    
    };
    
    $scope.$watchGroup(arrayOfValues, function(newValues, oldValues, scope) {
        var last_changed = $scope.checkWhichVariableHasUpdated(arrayOfValues, newValues, oldValues);
        if (angular.isDefined(last_changed)) {
            $scope.mySwitchFunction(last_changed)
        }
    });
    

    I hope this clears things up.