S
S
shipovalovyuriy2015-06-09 20:37:13
Angular
shipovalovyuriy, 2015-06-09 20:37:13

How to resolve this Angular js error?

An error like
Uncaught Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: []
html:

<!-- Loading libraires -->
<link rel="stylesheet" href="css/style.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.js"></script>
<script src="http://code.jquery.com/jquery-1.11.3.js"></script>
<script type="text/javascript" src="js/script.js"></script>

<!-- Main app -->

<div class="search_wrapper" ng-app="searchApp">
<div class="app_wrap" ng-controller="searchCtrl">
  <div class="search_param">
    <nav class ='brands'>
      <li  ng-repeat="brand in brands">{{brand}}</li>
    </nav>
    <nav class ='cat'>
      <span class = 'parent_cat' ng-repeat="cat in cats track by $index">

      {{cat[1]}}

      {{getChildList(cat[0])}}
      
    <nav class="child_cat">
      <li ng-repeat="child in child_cats track by $index">{{child}}</li>
    </nav>
      
      </span>
    </nav>
  </div>
  <div class="form_search">
    <form action="">
      <input type="text">
    </form>
  </div>
  <div class="search_rezult">

  </div>
  </div>
</div>

js:
var searchApp = angular.module('searchApp',[]);

searchApp.controller('searchCtrl', ['$scope','$http', function($scope,$http){


/*Getting Manufacturers list*/

  var name  = " SELECT * FROM audio.w8265_virtuemart_manufacturers_ru_ru";
  
  $http({method:"GET",url:'ajax/index.php',params:{'type':name}}).success(function(response){
    response = angular.fromJson(response);
    console.log(response);
    var arr = [];
    var i = 0;
    $.each(response, function(index, val) {
      arr[i] = val.mf_name;
      i++;
    });
    $scope.brands = arr;
    })

  /*Getting Parent Categories list*/
    name = "SELECT virtuemart_category_id, category_name FROM audio.w8265_virtuemart_categories_ru_ru join audio.w8265_virtuemart_category_categories on virtuemart_category_id = category_child_id where category_parent_id = 0"
    $http({method:"GET",url:'ajax/index.php',params:{'type':name}}).success(function(response){
    response = angular.fromJson(response);
    console.log(response);
    var arr = [];
    var i = 0;
    $.each(response, function(index, val) {
      arr[i] = new Array();
      arr[i][0]= val.virtuemart_category_id;
      arr[i][1]= val.category_name;
      console.log(arr[i]);
      i++;
    });
    $scope.cats = arr;
    })


    $scope.child_cats = [];

  /*Getting Child Categories list*/
    $scope.getChildList = function(parent){
    name = "SELECT category_name FROM audio.w8265_virtuemart_categories_ru_ru join audio.w8265_virtuemart_category_categories on virtuemart_category_id = category_child_id where category_parent_id ="+parent;
    $http({method:"GET",url:'ajax/index.php',params:{'type':name}}).success(function(response){
    response = angular.fromJson(response);
    console.log(response);
    var arr = [];
    var i = 0;
    $.each(response, function(index, val) {
      arr[i] = new Array();
      arr[i]= val.category_name;
      console.log(arr[i]);
      i++;
    });

    $scope.child_cats = arr;
    })

    }
}]);

Also, could you advise: what can be changed in the structure, etc.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
Sergey, 2015-06-09
@shipovalovyuriy

1 - the $scope.getChildList method is called for every $digest cycle
2 - every $scope.getChildList call generates a request to the server via $http
3 - each completed $http call (and indeed a status change) generates a $digest cycle
4 - back to the first point

// Все люди ходят в туалет
// но обычно делают это в одном месте
function dataProviderFactory($http, $q) {

    return {
        getManufactures: getManufactures,
        getCategories: getCategories,
        getCategoryTree: getCategoryTree
    };

    function getManufactures () {
        var sql = 'SELECT * FROM audio.w8265_virtuemart_manufacturers_ru_ru';

        return exec(sql)
            .then(function (data) {
                return pluck(data, 'mf_name');
            }, repeatError);
    }

    function getCategories(pid) {
        var sql = 'SELECT virtuemart_category_id, category_name FROM audio.w8265_virtuemart_categories_ru_ru join audio.w8265_virtuemart_category_categories on virtuemart_category_id = category_child_id where category_parent_id = ' + (pid || 0);

        return exec(sql)
            .then(function (data) {
                return pluck(data, 'category_name');
            }, repeatError);
    }

    // а еще лучше уж тогда так:
    function getCategoryTree() {
        // get all categories
        var sql = 'SELECT virtuemart_category_id as id, category_name, category_parent_id as parent_id FROM audio.w8265_virtuemart_categories_ru_ru join audio.w8265_virtuemart_category_categories on virtuemart_category_id = category_child_id';

        return exec(sql)
            .then(function (categories) {

                return getChildren(categories);

                // простенький рекурсивный обход дерева
                function getChildren(collection, pid) {
                    pid = pid || 0;

                    return collection.filter(function (item) {
                        return item.parent_id == pid;
                    }).map(function (category) {

                        return {
                            name: category.category_name,
                            children: getChildren(collection, category.id)
                        }
                    });
                }
            }, repeatError);
    }

    // я думаю не стоит даже говорить насколько это плохо....
    // я надеюсь что никто не увидит эту систему кроме как менеджеры какие-нибудь...
    // ибо это нехилая такая дыра в безопасности
    // да и вообще стремно
    function exec(sql) {

        return $http
            .get('/ajax/index.php')
            .then(function (response) {
                // а если вы на сервере укажите Content-type application/json
                // Angular будет делать вам это автоматом
                return angular.fromJson(response.data);
            }, repeatError);
    }

    function repeatError(reason) {
        return $q.reject(reason)
    }

    function pluck(collection, key) {

        return collection.map(function (item) {
            return item[key];
        });
    }
}

// чистенький контроллер
function SearchController (dataProvider) {
    var vm = this;

    dataProvider.getCategoryTree().then(function (tree) {

        vm.categories = tree;
    });
}

well, yes. use controller as syntax:
<div ng-controller="SearchController as search">
    <ul>
       <li ng-repeat="item in search.tree">
</div>

in short, the idea is simple - you didn't have to pull this controller method at all or do it at all.
one more note, you did just terrible things in the controller and at the same time you use track by without clearly understanding what it is and why it is needed.

_
_ _, 2015-06-09
@AMar4enko

The problem is
{{getChildList(cat[0])}}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question