0

I have pieces of data that come back in a very strange form (A single string representing all the choices/labels of a radio button group).

Example:

"yes|Yes no|No"

Because of this, I have to transform it into an array of pair objects. I do this with a function on my controller that iterates over the data one splitting on the newline character and then for each item in that array, it creates a pair obj with a value and a label attribute then pushes it into an array. At the end of the function, the final array is returned. The result would look like

[{value:"yes", label:"Yes"},{value:"no"|label:"No"}]

my markup looks like the following:

<div ng-repeat="item in function(dataObj)"></div> 

I know this error is occurring because angular expects the same object to return twice, as per other topics with similar issues. However, I don't see how to fix this issue.

As of right now, the function is actually working flawlessly, but I don't want to leave the error in..

Conqueror
  • 4,265
  • 7
  • 35
  • 41
  • Is there a property on the object that uniquely identifies it, either `value` or `label`? – Chandermani Oct 16 '13 at 15:06
  • Not quite, Basically, I get a giant string and then I break it up into objects (which represent pairs), and finally return an array. The giant strings themselves are part of a much larger collection of objects, but not are not mandatory to exist. – Conqueror Oct 16 '13 at 15:34

1 Answers1

3

Ng-repeats are constantly evaluated on every digest cycle - which means your function will be called over and over. You are creating a new object on every cycle, which causes angular to keep reevaluating, leading to the problem you've explained (full explanation here). Ideally you should always be calling ng-repeat against static data:

$scope.data = function(dataObj);

And setting your markup as:

<div ng-repeat="item in data"></div> 
Community
  • 1
  • 1
B Cotter
  • 951
  • 5
  • 7
  • I am not working with static data, but instead, a large array of dynamic data. The data string may exist on some objects and not on others, and the function will need to be called on all instances of the said data string. – Conqueror Oct 16 '13 at 14:40
  • You will need to call the function elsewhere, and put the data on your $scope, as and when required. You should always be firing your ng-repeat on a static piece of data. There are some elaborate ways of getting around it, but it's not the recommended way of dealing with it. See the full explanation here: http://stackoverflow.com/questions/12336897/how-to-loop-through-items-returned-by-a-function-with-ng-repeat – B Cotter Oct 16 '13 at 15:33
  • I suppose the question is, how can I transform the giant strings (which are part of a larger object), into an array of pairs? Can I do something like $scope.data.x.y.z = function($scope.data.x.y.x), where $scope.x.y.z represents the dataObj (giant string being manipulated into an array of pairs) – Conqueror Oct 16 '13 at 15:36
  • I believe you said you had a method for doing that? Here is a fiddle which does what you explained (and reproduces the digest issue) http://jsfiddle.net/HB7LU/727/ . So you want to call the function on your object, attach the data to your scope, and then ng-repeat that data. – B Cotter Oct 16 '13 at 15:39
  • I do have a method for it, but the data is one of many instances (which may or may not exist), for example Imagine an collection of 100 objects. 20 of those objects contain $scope.data.x.y.z at 3 levels down in the object. The other 80 objects don't contain $scope.data.x.y.z, How can I statically provide the manipulated version of $scope.data.x.y.z without iterating the entire object? – Conqueror Oct 16 '13 at 15:42
  • Check for the presence of this long string of data on each object, and if it is present, call the function and replace/add the returned array of value/labels to the object. Your ng-repeat bindings will update automatically, assuming they're bound to wherever you're putting the processed data in your scope. – B Cotter Oct 16 '13 at 15:47
  • I accepted this, but there is an extra step, I added a watch on the data coming back then I modify it by iterating over the object as you mentioned and calling the function where appropriate. I would update the answer for future viewers to include some info you mentioned during the comments. – Conqueror Oct 16 '13 at 19:11
  • `Ideally you should always be calling ng-repeat against static data` Does this mean that you should not have `item in item.getAll()` code in the `view`? I had similar code `for item in item.getAll()` that returned an array of JSON objects `[{name: "Kevin"}, {name: "Bill}, etc.]`. When I switched from `item in item.getAll()` to `item in data` (where `$scope.data = item.getAll()`), I no longer had the `10 Digest iterations reached` error. – Kevin Meredith Jan 05 '14 at 02:45