AngularJS - error: [$ rootscope: infdig] 10 $ digest () iterations reached

I am new to AngularJS and am facing a problem.

I have an array of JSON invoices obtained with a $ http GET request, which is done here:

  <a ng-repeat="invoice in invoices" href="#" class="list-group-item">
    {{ invoice[data]["TxnDate"][0] }} -
    {{ invoice[data]["DocNumber"][0] }} - 
    ${{ invoice[data]["TotalAmt"][0] }} - 
    {{ getCustomer(invoice[data]["Id"][0]) }}

    <i class="fa fa-chevron-right pull-right"></i>
    <i class="pull-right">Edit</i>
  </a>

      

The problem is that the invoice array does not store customer information other than the customer reference number.

So, I created a function called getCustomer

that asks my API for a customer name by their reference number.

$scope.getCustomer = function(id) {

    var customer_id = id.match(/\d+/)[0];

    $http.post('/customers', customer_id).success(function(response) {
        console.log(response);
    });

};

      

The problem is I am getting this error:

error: [$rootscope:infdig] 10 $digest() iterations reached. aborting! watchers fired in the last 5 iterations: []

      

I'll figure out a more efficient way to do this later, but I'm curious to know what is causing this error?

After some research I think it has something to do with the fact that after changing the data in one of the list items AngularJS needs to check all the list items. However, I am very confused. What is the correct way to do this?

+3


source to share


1 answer


The problem is related to using the function inside the binding ({{}} interpolation). Due to its nature, angularjs is constantly watching the $ scope (view model) for changes. So if you're not careful, you can bind to a function that always returns a new / different instance of the object. This causes an endless loop which angular identifies as an error and disables the binding to avoid stackoverflow. If you say that you changed your function to store the returned client in a local variable, you might be able to avoid this problem.

Here is the complete snippet.



var app = angular.module('main', []);

app.controller('MainCtrl', function($scope, $http, $q) {
  $scope.invoices = [
    { Id: "1", TxnDate: new Date(2014, 6, 26), DocNumber: "I001234", TotalAmt: 200.34 }, 
    { Id: "2", TxnDate: new Date(2014, 8, 2), DocNumber: "I000021", TotalAmt: 530.34 }, 
    { Id: "3", TxnDate: new Date(2014, 11, 15), DocNumber: "I000023", TotalAmt: 123 },  
    { Id: "4", TxnDate: new Date(2014, 12, 11), DocNumber: "I000027", TotalAmt: 5000 },  
  ];
  
  var testUrl = 'http://echo.jsontest.com/company/AKME/firstName/John/lastName/Doe';
  var _customerCache = {};
  $scope.customerCache = _customerCache;
  $scope.getCustomer = function(id) {
    var deferred = $q.defer(); // defer
    if (_customerCache[id])
        return deferred.resolve(_customerCache[id]);
    
    var customer_id = id.match(/\d+/)[0]; 

    $http.get(testUrl + customer_id + '/id/'+ customer_id).success(function(response) {
        console.log(response);
        _customerCache[id] = response;
        deferred.resolve(response);
    });
    return deferred.promise;
};
});
      

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div  ng-app="main"  ng-controller="MainCtrl">
  <ul>
    <li ng-repeat="invoice in invoices" ng-init="getCustomer(invoice.Id)">
    <a href="#" class="list-group-item">
      {{ invoice.TxnDate | date }} -
      {{ invoice.DocNumber }} - 
      {{ invoice.TotalAmt | currency }}
      {{ customerCache[invoice.Id].firstName }} {{ customerCache[invoice.Id].lastName }}
    </a>
    </li>
  </ul>
  <span>customers via http</span>
  <ul>
    <li ng-repeat="cust in customerCache">
      {{cust}}
    </li>
  </ul>
<div>
      

Run code


+6


source







All Articles