title: AngularJS $watch - infinite loop
body: <p>I have 2 dates - start and end. I want to validate (and re-assure) start &lt; end.
  I get notified they change using $watch, and then I go and change them to make sure the condition is met, but then it triggers the $watch again and then I get max iterations reached of $digest and things go south.</p>
  
  <p>So my question is - how do I change variables that are watched inside the <code>$watch</code> without causing infinite cycle. (Aside from having more checks and changing them only if they actually needs to be changed)</p>
  
  <p>Here is my code:</p>
  
  <pre><code>var TIME_DAY = 1000 * 60 * 60 * 24;
  
  $scope.$watch('timeFilter.startTime', function () {
      validateStartEndTime();
  },true);
  
  $scope.$watch('timeFilter.endTime', function () {
      validateStartEndTime();
  },true);
  
  function validateStartEndTime() {
      if ($scope.timeFilter.startTime != null &amp;&amp; $scope.timeFilter.endTime != null) {
          // Remove all seconds
          if ($scope.timeFilter.startTime.getSeconds() &gt; 0)
              $scope.timeFilter.startTime.setSeconds(0);
          if ($scope.timeFilter.endTime.getSeconds() &gt; 0)
              $scope.timeFilter.endTime.setSeconds(0);
          if ($scope.timeRange.minTime.getSeconds() &gt; 0)
              $scope.timeRange.minTime.setSeconds(0);
          if ($scope.timeRange.maxTime.getSeconds() &gt; 0)
              $scope.timeRange.maxTime.setSeconds(0);
  
          // When start time isn't before end time
          if ($scope.timeFilter.startTime &gt;= $scope.timeFilter.endTime) {
              // We want to increase end time by 1 minute, if possible - do it. Else - reduce start time by 1 minute
              if ($scope.timeFilter.endTime &lt; $scope.timeRange.maxTime) {
                  $scope.timeFilter.endTime.setMinutes($scope.timeFilter.startTime.getMinutes() + 1);
              } else {
                  $scope.timeFilter.startTime.setMinutes($scope.timeFilter.startTime.getMinutes() - 1);
              }
          }
  
          // Start time before min time
          if ($scope.timeFilter.startTime &lt; $scope.timeRange.minTime) {
              $scope.timeFilter.startTime = $scope.timeRange.minTime;
              if ($scope.timeFilter.endTime &lt;= $scope.timeFilter.startTime) {
                  $scope.timeFilter.endTime = $scope.timeFilter.startTime;
                  $scope.timeFilter.endTime.setMinutes($scope.timeFilter.endTime.getMinutes() + 1);
              }
          }
  
          // End time after max time
          if ($scope.timeFilter.endTime &gt; $scope.timeRange.maxTime) {
              $scope.timeFilter.endTime = $scope.timeRange.maxTime;
              if ($scope.timeFilter.startTime &gt;= $scope.timeFilter.endTime) {
                  $scope.timeFilter.startTime = $scope.timeFilter.endTime;
                  $scope.timeFilter.startTime.setMinutes($scope.timeFilter.startTime.getMinutes() - 1);
              }
          }
      }
  }
  </code></pre>