3

Assume the following JSON structure, which is strongly simplified from what I am currently working with:

$scope.var1 = {
    "test1": {
        "name": "test1",
        "belongsTo": "var1",
        "additionalInformation": "blabla"
    },
    "test2": {
        "name": "test2",
        "belongsTo": "var1",
        "additionalInformation": "blabla"
    },
    "test3": {
        "name": "test3",
        "belongsTo": "var1",
        "additionalInformation": "blabla"
    }
};

$scope.var2 = {
    "test8": {
        "name": "test8",
        "belongsTo": "var2",
        "additionalInformation": "blabla"
    },
    "test2": {
        "name": "test2",
        "belongsTo": "var2",
        "additionalInformation": "blabla"
    },
    "test9": {
        "name": "test9",
        "belongsTo": "var2",
        "additionalInformation": "blabla"
    }
};

$scope.valuesVar1 = {
    "test1": {
        "value": 1
    },
    "test2": {
        "value": 2
    },
    "test3": {
        "value": 3
    },
};

$scope.valuesVar2 = {
    "test8": {
        "value": 4
    },
    "test2": {
        "value": 5
    },
    "test9": {
        "value": 6
    },
};

Var1 and Var2 represent some data, which always has the same structure. Same for valuesVar1 and valuesVar2 - they have the same structure and contain some additional information for var1 and var2.

I am trying to iterate over var1 and get the value from valuesVar1 using ng-init. On user interaction the assignment for the iteration is changed to var2, so know we are iterating over var2 and getting the values from valuesVar2.

The problem: When iterating over var2, we should get the value 5 for "test2". But since ngInit already "knows" test2 from iterating over var1, the value stays 2.

Note: Please don't give answers advising to change the JSON structure or something similar - because I am on my side not able to do this. I already tried to copy the object like proposed here: angularjs - ngRepeat with ngInit - ngRepeat doesn't refresh rendered value - but this doesn't work. I assume it is because ngInit "remembers" the string value "test2" rather than the object reference (but I don't really know it :) ).

Question: How can I get ngInit to run again on an iteration, where the same key for an object was already used in a previous iteration?

I also prepared a jsfiddle http://jsfiddle.net/S329r/6/ with the information. On running it iterates over var1 and outputs the values like this:

test1: 1
test2: 2
test3: 3

So far so good, I expect this. But when var2 is assigned for the iteration, the following shows:

test2: 2
test8: 4
test9: 6

Here I expect test2 to display the value 5. (Hint: In the jsfiddle demo, the button "Change" changes the assignment for the iteration to var2, "Change Back" changes it back to var1).

Community
  • 1
  • 1
meberhard
  • 1,797
  • 1
  • 19
  • 24

1 Answers1

4

One solution is to ensure that you are generating a unique Id for each item in the JSON. Of course you can't alter your JSON as you said, but you CAN force angularJS to generate one.

Put this in your repeat loop:

iter in iterateOver track by $id(iter.name + iter.belongsTo)

And as long as that combination of data is unique, your loop will work correctly.

A little more info from the documentation:

For example: item in items track by $id(item). A built in $id() function can be used to assign a unique $$hashKey property to each item in the array. This property is then used as a key to associated DOM elements with the corresponding item in the array by identity. Moving the same object in array would move the DOM element in the same way in the DOM.

EDIT Another solution is to change your loop a little and don't use ng-init Instead, get your values like this:

<div ng-repeat="iter in iterateOver " >
    {{iter.name}}: {{getValForIter(iter).value}}
</div>
Caspar Harmer
  • 8,097
  • 2
  • 42
  • 39
  • good point! Yesterday night in the shower I also got the idea to just call the method :) Glad, that it works! I updated the jsfiddle for future reference: http://jsfiddle.net/S329r/11/ Thanks! – meberhard Aug 05 '14 at 05:38
  • Yeah, I found that fiddle useful - I had a read of the docs and mucked around with it to figure it out. Was thinking you might not like it as a solution as it doesn't really answer your reset question - it kind of sidesteps it. – Caspar Harmer Aug 05 '14 at 07:14
  • also true, but it works for now. I searched for ways to "reset" ngInit or to "delete the cache", but didn't find anything. Maybe it's just not intentional behaviour. Anyway, if someone finds the "real answer" to this question, it still can be added here :) – meberhard Aug 05 '14 at 07:32