Home > Mobile >  Why does using .match inside of an ng-if seem to cause digest cycles
Why does using .match inside of an ng-if seem to cause digest cycles

Time:04-29

Consider the following simple angularjs app (fiddle here: https://jsfiddle.net/jeconner/n3e61o0a/33/):

<div ng-controller="MyCtrl">
  <div ng-if="showVal()">
    {{val}}
  </div>
</div>
var myApp = angular.module('myApp',[]);

//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});

function MyCtrl($scope, $interval) {
    $scope.val = 0;
    
    $interval(function () {
        $scope.val = Math.trunc(Math.random() * 200);
    }, 1000);
    
    $scope.showVal = function () {
        //return $scope.val % 2 == 0; // This works!
        return String($scope.val).match(/[1]{1}[0-9]{2}/); // Console errors!
    };
}

The value of val is set to change every second. If you uncomment the first return line in showVal, this runs without error, showing val when it is even.

However, if you convert val to a string and test against a regex like the one above, there is a console error complaining about 10 digest cycles being reached:

<a class='gotoLine' href='#"Error: [$rootScope:infdig'>"Error: [$rootScope:infdig</a> 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: <a class='gotoLine' href='#[\&quot;showVal(); newVal: [\\&quot;176\\&quot;]; oldVal: [\\&quot;176\\&quot;]\&quot;],[\&quot;showVal(); newVal: [\\&quot;176\\&quot;]; oldVal: [\\&quot;176\\&quot;]\&quot;],[\&quot;showVal(); newVal: [\\&quot;176\\&quot;]; oldVal: [\\&quot;176\\&quot;]\&quot;],[\&quot;showVal(); newVal: [\\&quot;176\\&quot;]; oldVal: [\\&quot;176\\&quot;]\&quot;],[\&quot;showVal(); newVal: [\\&quot;176\\&quot;]; oldVal: [\\&quot;176\\&quot;]\&quot;]'>[\&quot;showVal(); newVal: [\\&quot;176\\&quot;]; oldVal: [\\&quot;176\\&quot;]\&quot;],[\&quot;showVal(); newVal: [\\&quot;176\\&quot;]; oldVal: [\\&quot;176\\&quot;]\&quot;],[\&quot;showVal(); newVal: [\\&quot;176\\&quot;]; oldVal: [\\&quot;176\\&quot;]\&quot;],[\&quot;showVal(); newVal: [\\&quot;176\\&quot;]; oldVal: [\\&quot;176\\&quot;]\&quot;],[\&quot;showVal(); newVal: [\\&quot;176\\&quot;]; oldVal: [\\&quot;176\\&quot;]\&quot;]</a>
http://errors.angularjs.org/1.2.1/$rootScope/infdig?p0=10&amp;p1=[["showVal(); newVal: [\"176\"]; oldVal: [\"176\"]"],["showVal(); newVal: [\"176\"]; oldVal: [\"176\"]"],["showVal(); newVal: [\"176\"]; oldVal: [\"176\"]"],["showVal(); newVal: [\"176\"]; oldVal: [\"176\"]"],["showVal(); newVal: [\"176\"]; oldVal: [\"176\"]"]]
    at https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.js:78:12
    at Scope.$digest (https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.js:11472:19)
    at Scope.$apply (https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.js:11682:24)
    at tick (https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.js:8189:36)"]
"Script error."

Why does this error occur? Is there a proper way for using regex inside of an ng-if that avoids this error?

CodePudding user response:

I try not to have functions as my ng-show or ng-if. They get called non-stop, often unnecessarily. I have found it's alot easier on memory and performance to use booleans that are set behind the scenes. For example, in your code it's setting $scope.val every second, but might be running the showVal() function many, many times during digests. Consider this alternate, which I tested in a fiddle without errors:

<div ng-controller="MyCtrl">
  <div ng-if="showValBool">
    {{val}}
  </div>
</div>
var myApp = angular.module('myApp',[]);

function MyCtrl($scope, $interval) {
    $scope.val = 0;
    $scope.showValBool = false
    $interval(function () {
        $scope.val = Math.trunc(Math.random() * 200);
        $scope.showValBool = String($scope.val).match(/[1]{1}[0-9]{2}/);
    }, 1000);
    
} 
  • Related