2

In angular the use of Track by to track selection by value instead of by reference is a nice feature if needed. But lets say I switch the array behind and the selected object id matches a new Id I want the select to change as well

How do I force it to reevaluate?

HTML:

    <select ng-options="option.id for option in collection track by option.id" ng-model="selectedObject"></select>
    <button ng-click="updateCollection()">Update</button>

JS:

    $scope.collection = [{
            id: 1,
            value: 0
        }, {
            id: 2,
            value: 0
        }, {
            id: 3,
            value: 0
        }];

    $scope.selectedObject = $scope.collection[0];

    $scope.updateCollection = function () {
        var newColl = [{
            id: 1,
            value: 100
        }, {
            id: 2,
            value: 200
        }, {
            id: 3,
            value: 300
        }];

        $scope.collection = newColl;

Lets say I pick Id 2 and then update the selectedObject is still the old id:2 value:0, I want it to change straight into id:2 value:200.

https://jsfiddle.net/IngoVals/p4ye3uaq/

P.S. Why doesn't the angular.copy work in the fiddle?

Ingó Vals
  • 4,468
  • 14
  • 57
  • 108

1 Answers1

2

when you pick Id 2 then option model selectedObject is the second object of the collection which has Id of 2.

Then you press the update button and change $scope.collection at this point optoins will change in the select box, but the selected value is never changed, its still reference to the second object of the previous $scope.collection. so you need to update the selected value as well to do that,

get the selected object's index as,

 var selectedIndex = $scope.collection.indexOf($scope.selectedObject);

assign the new collection as you did,

$scope.collection = newColl;

finally update the selectedObject based on that previously selected object's index.

$scope.selectedObject = $scope.collection[selectedIndex];

here is the DEMO

Kalhan.Toress
  • 20,702
  • 5
  • 63
  • 84
  • Could this be changed where instead of using index you use the actual property being tracked? Lets say the new collection doesn't have the same order, or the tracked id isn't even a number, just a unique string. Like this: https://jsfiddle.net/IngoVals/sdqtq2yL/1/ – Ingó Vals May 01 '15 at 16:10
  • This won't work. It only appears to work because, coincidentally, the OP replaced the collections with items that are in the same indexed order. The index that you are calculating is derived from the old list, so if the new list had items 1 sorted to the end, you'll see you are getting the wrong selection. – Michael Hays May 01 '15 at 16:23