I have been developing a few prototype apps in Angular, with various backends, including firebase and php/mysql. I'm pretty sure I'm not using a good organization pattern for development because of a couple of kluges I have to use in the code to avoid the "max digest iterations reached" exception.
I have a template with an ng-repeat, like this:
<ion-item data-ng-repeat="outcome in Outcomes.getAll()">...</ion-item>
It is supported by a service like this:
'use strict';
angular.module('app.outcomes', ['app.utility']).service('Outcomes', function ($http, Utility) { var svc = this; svc.outcomes = false;
/**
* Initializes the outcomes array if it has not yet been initialized.
*
* @returns {Array}
*/
svc.initialize = function () {
if (svc.outcomes === false) {
// If this is not set to something immediately, repeated calls to
// digest occur during http call and digest overloads.
svc.outcomes = true;
$http.get('/api/outcome/all').
success(function (data, status, headers, config) {
svc.outcomes = data.result; // set data to real array value
}).
error(function (data, status, headers, config) {
});
}
};
/**
* Called in ng-repeat so that it makes sure the data is initialized.
* An ng-init call does not work.
* @returns {Array}
*/
svc.getAll = function () {
svc.initialize(); // called constantly from ng-repeat, while array actually set
return svc.outcomes;
};});
The controller is a one-liner that sets the $scope.Outcomes variable to the service.
This strategy works, because the digest loop tests the condition. What seems klugy to me is that I need to set the outcomes array to some unused value while I wait for the ajax call to return. Otherwise the digest loop is called and it tries to keep doing it for however long the call takes to return from the server.
Another related problem I have is that if I set the svc.outcomes array later, I will sometimes get the same error about too many digest iterations.
The questions I have are:
1) Is there a better way to organize the code? I need to be able to access that server data across multiple scopes.
2) Is there a way to ensure that the data array gets initialized without having to call the getAll() method in the ng-repeat loop? An ng-init call doesn't populate the data, so I can't just reference Outcomes.outcomes in the template.
What is strange to me is that I think the "max iterations" thing just started happening with using a minor update (1.3.3 to 1.3.6) to angular. That could be my imagination though. Any architectural suggestions would be appreciated.