Within the method of my factory, I am retrieving an array from the server using 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;
In my HTML template, I have the following (where the service is named vms in the template):
<div ng-repeat="machine in vms.getRunningVMs(true) track by machine.id">{{machine.owner}} {{machine.host}}</div>
This resulted in 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"]]
This issue arises because each method call returns a new array every time, which fails Angular's equality check for watched collections.
I attempted to use track by
:
<div ng-show="managing === 'machines'" ng-repeat="machine in vms.getRunningVMs(true) track by machine.id">{{machine.owner}} {{machine.host}}</div>
However, this led to 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
Even though id
is defined, and the same error occurs when tracking by $index
.
Could it be that track by
is not designed to handle functions that return new arrays, even with explicit usage? While initially intended to prevent unnecessary DOM manipulation, it seems like there could be a way to make it work in such scenarios.