Iraitz Iraitz - 1 year ago 55
AngularJS Question

Error of iterations using $scope.$watch

It's my first time posting here so I hope you can help.

Im having a problem using $scope.$watch. The thing is that I want to control 2 DateTime Fields on a Form and when 1 of them change, calculate the difference between them in Days to fill another number input of the Form. The problem is that when I run the app and change a Date the consolo shows me this:

Here is the code I use.

function handleFechaChange(newValue, oldValue) {
console.log('newValue: ' + newValue + ', oldValue: ' + oldValue);
if (newValue !== oldValue) {

vm.calculoDecalaje = function () {
vm.siniestro.fechaOcurrencia = moment(vm.siniestro.fechaOcurrencia);
vm.siniestro.fechaComunicacion = moment(vm.siniestro.fechaComunicacion);
vm.siniestro.decalaje = vm.siniestro.fechaComunicacion.value - vm.siniestro.fechaOcurrencia.value;

Thank you.

Answer Source

You have an infinite loop - let's step through what's happening here:

  • vm.siniestro.fechaOcurrencia changes, causing your watch function (handleFechaChange) to be run.
  • handleFechaChange calls vm.calculoDecalaje();.
  • vm.calculoDecalaje changes vm.siniestro.fechaOcurrencia, causing your watch function to be run again, which causes vm.calculoDecalaje to be run again, which causes your watch function to run again...

After 10 digest cycles, Angular realizes that the values are never going to stabilize, so it kills the infinite loop to stop your browser from crashing. This is why you're getting the infinite digest error.

My recommendation would be to change your vm.calculoDecalaje function so that it doesn't mutate the input values:

vm.calculoDecalaje = function () {
    vm.siniestro.decalaje = moment(vm.siniestro.fechaComunicacion).value - moment(vm.siniestro.fechaOcurrencia).value;

That way your user input remains the 'source of truth' on what goes in to the function (which I find a bit easier to keep track of), and you don't cause your watcher to spiral out of control.