0
votes

Is there a bug related to forEach in AngularJS 1.2.21 that was not in AngularJS 1.2.20 ?

I tested the following code (when the ng-grid is loaded):

var contor = 0;
$scope.$watch('gridOptions.$gridScope.columns', functionForColumnsChange, true);
...
function functionForColumnsChange(newv, oldv) {
    if ( newv !== oldv ) {
        console.log(contor++);
    }
}

If I use:

https://ajax.googleapis.com/ajax/libs/angularjs/1.2.20/angular.js

the output is

0

but if I use

https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.js

the output is

TypeError: Cannot set property 'sortPriority' of undefined at http://angular-ui.github.io/ng-grid/lib/ng-grid.js:1668:36 at Object.forEach (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.js:325:18) at self.sortData (http://angular-ui.github.io/ng-grid/lib/ng-grid.js:1667:25) at self.sortColumnsInit (http://angular-ui.github.io/ng-grid/lib/ng-grid.js:1701:18) at Object.ngGridDirectives.directive.ngGridDirective.compile.pre.grid.init.then.dataWatcher [as fn] (http://angular-ui.github.io/ng-grid/lib/ng-grid.js:2943:42) at Scope.$get.Scope.$digest (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.js:12471:29) at Scope.$get.Scope.$apply (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.js:12736:24) at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.js:1438:15 at Object.invoke (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.js:3940:17) at doBootstrap (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.js:1436:14)

0

1

Why that error ? And why 1 after 0 ?

If I change the ng-grid.js commenting 2 lines:

//c.sortPriority = i + 1;
//push(c);

the error message is not there anymore, but there is "1".

The ng-grid that is used is from this source: http://angular-ui.github.io/ng-grid/lib/ng-grid.js (there is the same problem for the minified version).


Later edit: The problem seems to be related to this issue: https://github.com/angular/angular.js/commit/36625de0d3ebc1fc091af474d942c6ce16b0a1c0

The difference is only in Google Chrome and Mozilla Firefox.

In IE8 0 and 1 are printed for both versions of AngularJS. Output in IE8:

TypeError: 'undefined' is null or not an object

0

1

1
What is the bug with $watch..? The ng-grid library youre using is causing an error on the different angular version, what do you expect $watch to behave like? Do you know what's going wrong within the library and what it does on errors? - Philipp Gayret
Attach your code, make a JSFiddle, what you have now is not enough to reproduce the issue. The ng-grid is iterating over an array of columns and one of those is undefined. Try to make a JSFiddle that reproduces the issue on both versions. - Philipp Gayret
What you could do is replace the forEach function on the global angular object, and fall back on the old functionality you linked on Github. - Philipp Gayret
I found a workaround for this problem. I took the AngularJS code on my local machine and I added a condition before the line because the array seems to be sparse. So, I changed the forEach source code adding: if ( typeof obj[key] !== 'undefined' ) in the for loop. - Elrond_EGLDer
A better solution was to modify just ng-grid to work with the new AngularJS: if (isArr) { angular.forEach(col, function (c, i) { if ( typeof c !== 'undefined' ) { c.sortPriority = i + 1; push(c); } }); - Elrond_EGLDer

1 Answers

1
votes

The problem was that I had a wrong $scope.sortInfo array:

$scope.sortInfo = {fields: ["N", "A", "B", "C"], directions: ['asc']};

even if "N" is not a column at this moment.

I found 3 possible solutions:

1) Change the array:

$scope.sortInfo = {fields: ["A", "B", "C"], directions: ['asc']};

2) Change the ng-grid to be more permissive:

                if ( typeof c !== 'undefined' ) {
                    c.sortPriority = i + 1;
                    push(c);
                }

3) Change the AngularJS to be more permissive:

for (key = 0; key < obj.length; key++) {
    if ( typeof obj[key] !== 'undefined' ) {
        iterator.call(context, obj[key], key);
    }
}