3

I have some controllers like this:

app.controller("zipController", function($scope, $http, $rootScope, $timeout) {
  $scope.zipCodes = [];
  $scope.addZipCode = function() {
    $scope.zipCodes.push({code: '', distance: '25mi'});
  }
  $scope.removeZipCode = function(index) {
    console.log(index, 'index removing');
    $scope.zipCodes.splice(index, 1);
  }
});

app.controller("zipCodeController", function($scope, $http, $rootScope, $timeout) {

});

Here is the HTML:

<label ng-click="addZipCodes=!addZipCodes; addZipCode();"><i class="fa fa-map-marker" aria-hidden="true"></i> Target Zip Codes <small>(Cities)</small></label>
<span ng-if="addZipCodes" style="white-space: normal;">
    <span ng-repeat="code in zipCodes track by $index" class="zipCodeInput" ng-controller="zipCodeController">
        <span class="zipCodeText">
            <input type="text" placeholder="Zip Code" ng-model="zipCode" class="zipCode">
        </span>
        <span class="zipCodeSelect">
            <select ng-model="zipCodeDistance" ng-value="code.distance" class="zipCodeDistance">
                <option value="25mi">25 miles</option>
                <option value="50mi">50 miles</option>
                <option value="100mi">100 miles</option>
            </select>
        </span>
        <span class="zipCodeRemove">
            {{$index}}
            <a ng-click="removeZipCode($index)">x</a>
        </span>
    </span>
    <label ng-click="addZipCode();" class="addZipCode"><i class="fa fa-plus-square" aria-hidden="true"></i> Add</label>
</span>

When I call the removeZipCode($index) function it has the correct index, however it always removes the last $scope.zipCodes from the array, not the correct zip code index.

Any ideas why?

6
  • Could you please create a working snippet/JSFiddle that reproduce the problem ? Commented Jan 9, 2017 at 15:09
  • Is it returning the correct index in the console.log line? Commented Jan 9, 2017 at 15:11
  • @epascarello Yes it is returning the correct index Commented Jan 9, 2017 at 15:11
  • 2
    This is caused by the use of track by $index Commented Jan 9, 2017 at 15:12
  • @devqon What would be the correct way to do it? Commented Jan 9, 2017 at 15:12

3 Answers 3

1

Remove "track by $index". it will work.

Sign up to request clarification or add additional context in comments.

1 Comment

I created this fiddle that replicates the above structure, yet it does work with track by $index. How do you explain that? (jsfiddle.net/2yt04ztr/4)
1

you could use this

ng-repeat="(index,value) in array"

Comments

0

The ng-model directives inside the ng-repeat are breaking the rule: always have a dot "." in your ng-models

<span ng-if="addZipCodes" style="white-space: normal;">
    <span ng-repeat="item in zipCodes track by $index" class="zipCodeInput" ng-controller="zipCodeController">
        <span class="zipCodeText">
            <!-- REMOVE 
            <input type="text" placeholder="Zip Code" ng-model="zipCode" class="zipCode">
            -->
            <!-- always have a dot in your ng-model -->
            <input type="text" placeholder="Zip Code" ng-model="item.code" class="zipCode">
        </span>
        <span class="zipCodeSelect">
            <!-- REMOVE
            <select ng-model="zipCodeDistance" ng-value="code.distance" class="zipCodeDistance">
            -->
            <!-- always have a dot in your ng-model -->
            <select ng-model="item.distance" ng-value="item.distance" class="zipCodeDistance">
                <option value="25mi">25 miles</option>
                <option value="50mi">50 miles</option>
                <option value="100mi">100 miles</option>
            </select>
        </span>
        <span class="zipCodeRemove">
            {{$index}}
            <a ng-click="removeZipCode($index)">x</a>
        </span>
    </span>
    <label ng-click="addZipCode();" class="addZipCode"><i class="fa fa-plus-square" aria-hidden="true"></i> Add</label>
</span>

Because the ng-repeat directive creates a child scope for each item, when an ng-model directive omits a dot ., the model modifies items on the child scope and not the parent scope.

For more information, see AngularJS Wiki - The Nuances of Scope Prototypal Inheritance.

The DEMO on JSFiddle

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.