I have the problem, that custom filters are producing an infinit digest loop in angular-meteor. (Angular error description page)
I made a working example in this plunk with pure angular. When I try the same with angular-meteor in es6 style, the script is running in the infinit loop.
This is my controller
class MyController {
constructor($scope, $reactive) {
'ngInject';
$reactive(this).attach($scope);
this.items = [{ item: 'item1' }, { item: 'item2' }, { item: 'item3' }, { item: 'item4' }];
}
}
And this is the template
<div ng-repeat="item in vm.items | testFilter">
Item: {{item.item}}
</div>
The filter implementation just makes a copy of the original content (so it filters nothing but it's ok for demonstration).
[...]
.filter('testFilter', () => {
return (items) => {
var result = angular.copy(items);
// maybe splice some elements from result
return result;
};
})
[...]
I don't understand the reason why this is working in plain angularjs but not working in meteor. Is it because of the es6=>es5 translation? Am I missing something and using filters the wrong way? Or did I find an angular-meteor bug?
I'd be glad for some advice. :)
I created a generic workaround for this problem, so when migrating an existing angular application to meteor, the logic of custom filters can stay untouched in many cases. (Gist with comments)
.filter('fixLoopFilter', () => {
const instanceCache = {};
return (items) => {
const hash = CryptoJS.SHA1(angular.toJson(items)).toString();
if (!instanceCache[hash]) instanceCache[hash] = [];
instanceCache[hash].length = 0;
items.map((item) => {
instanceCache[hash].push(item);
});
return instanceCache[hash];
};
})
It doesn't really filter any element of the input array but returns a clone of the input. The clone is the same instance for each input configuration. It's not a deep clone. If the input array contains objects, the result array will contain the same instances.
Usage:
Use it in your template as the last filter applied in a chain:
ng-repeat="vm.items | customFilter | fixLoopFilter"
Drawbacks:
This filter can be performance and memory consuming for a large input array or a large Array of objets. It is just meant as a workarount till the issue is fixed or there is a better workaround for this issue.