In my factory's method, I return an array from the server with Angular's $resource:
var resource = $resource("vm", {
session: function() {
return Auth.token();
},
all: '@all',
vmId: '@vmId'
}, {
listVM: {
method: 'GET',
url: _baseUrl + 'vm/machines',
isArray: true,
cache: false
}
}
...
_obj.getRunningVMs = function(all) {
return resource.listVM({all: all}).$promise;
};
...
return _obj;
And in my HTML I have (with the service aliased as vms in the template):
<div ng-repeat="machine in vms.getRunningVMs(true) track by machine.id">{{machine.owner}} {{machine.host}}</div>
This caused an infinite digest error:
Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations:
[["fn: $watchCollectionWatch; newVal: 22; oldVal: 19"],
["fn: $watchCollectionWatch; newVal: 25; oldVal: 22"],
["fn: $watchCollectionWatch; newVal: 28; oldVal: 25"],
["fn: $watchCollectionWatch; newVal: 31; oldVal: 28"],
["fn: $watchCollectionWatch; newVal: 34; oldVal: 31"]]
which I know is caused by the fact that the method call returns a brand new array every time, which fails Angular's equality check for watched collections.
I tried track by:
<div ng-show="managing === 'machines'" ng-repeat="machine in vms.getRunningVMs(true) track by machine.id">{{machine.owner}} {{machine.host}}</div>
which caused the following error:
Error: [ngRepeat:dupes] Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: machine in vms.getRunningVMs(true) track by machine.id, Duplicate key: undefined, Duplicate value: undefined
I know that id is defined, and I get the same error when tracking by $index.
Is track by not meant for dealing with functions that return new arrays, even with track by? I know it was originally meant to avoid needless DOM mutation, but it seems like it could easily be made to work in this situation.