0

UPDATE: Found what is likely the same or nearly the same issue: AngularJS: ng-repeat list is not updated when a model element is spliced from the model array

What ended up working for me is changing the filter function down below with the following:

$scope.deleteRole = function (roleID) {
    var pickIndex = findWithAttr($scope.dtbRole, "ROLEID", roleID); //to find array index       
    $scope.dtbRole.splice(pickIndex, 1);
    $scope.$apply();
  }

I thought I had a decent understanding of when not to use $apply(), but I guess this is one place to use it. Are there any disadvantages to this?

Original Text:

I apologize if there is a direct answer to this, but searching with several dozen combinations of terms has resulted in a lot of nothing for me, partly due, I'm sure, to ngRepeat's filter and JS's filter method sharing a name. I have found answers to literally hundreds of questions on here without ever posting, but I've come up empty-handed on this one.

I'm new to Angular as of late last year, but I've learned a lot over the last few months (largely thanks to this site!). I have an ngRepeat working near-perfectly (I'll get to that "near-" in a moment):

<tr ng-repeat="role in dtbRole | orderBy:'-PERCENT'">  
  <td>
    <input ng-model="role.PERCENT" class="form-control" type="text" />
  </td>
  <td>
    <input ng-model="role.DESCRIPTION" class="form-control" type="text" />
  </td>
  <td>
    <button type="button" class="btn btn-danger" ng-click="deleteRole(role.ROLEID)">
      &times;
    </button>
  </td>
</tr>

The script that runs within that delete button is pretty straightforward:

$scope.deleteRole = function (roleID) {        
  $scope.dtbRole = $scope.dtbRole.filter(function (obj) {
    return obj.ROLEID !== roleID;
  });
}

I've thrown in some console.log() lines throughout to make sure it's doing what it should, and it is. The weird part, and the reason I say it's working near-perfectly, is that in the webpage itself, the visual isn't updated until I click in and out of the inputs within the item that should be deleted, and sometimes I have to do that a few times before it happens. I can't figure out what exactly triggers the update, but simply doing nothing will not update it (tried going on a 15-minute break, to no avail). The JS console insists that dtbRole is updated immediately. No performance spikes, no traffic delays, no freezing or choppiness... I'm stumped. I even did a few simple remakes on jsfiddle to see if I could replicate the issue, and I can't. It's instantaneous everywhere else, and I can't spot what's different.

What's more, I have another area after the ngRepeat to add items to dtbRole, and it updates instantaneously in the visual:

$scope.addRole = function (perc, desc) {
  $scope.dtbRole.push({ "ROLEID": idGen(), "PERCENT": perc, "DESCRIPTION": desc });
  $scope.addRolePercent = ''; //clear input
  $scope.addRoleDesc = ''; //clear input
}

It all seems simple enough, but after a few days of this, I'm going to admit that I need a few more pairs of eyes to see what I'm doing wrong.

So I ask if there's some glaring mistake that is obvious to a more veteran Angular or JS developer, or if there's a different technique I could use to achieve the same effect.

6
  • do you want to descending by orderBy:'-PERCENT' Commented May 13, 2016 at 19:27
  • Oh, sorry! That orderBy part isn't important to me, that's just how I currently have it set up. I tried the same thing without it, and it didn't change the issue. Commented May 13, 2016 at 19:39
  • I don't know the reason, as I am quite perplexed, but a debugging thing to try would be using a mutating function on the array directly rather than re-assigning it. Maybe a .splice() or something? Commented May 14, 2016 at 0:42
  • @JohnGrinsell Well, can't exactly say without debugging. But, I am guessing one of the possible problem may be, you are creating dtbRole array everytime with the filter function. That might cause problem with the ng-repeat directive to manipulate the array again and build new dom structure again. One thing you can try is to use track by syntax in ng-repeat. e.g. ng-repeat="role in dtbRole track by $index". Just use track by with a unique key of the array object. If no unique key available, then use track by $index. Let me know what happens. Commented May 14, 2016 at 10:54
  • @sourdoughdetzel @Saad Wow, I like .splice() a LOT. Thanks for that! Though the issue remains after using that and using track by role.ROLEID or track by $index. I'm thinking it's got to be something else in my code. It is kind of a bulky script for being a single controller - 33 functions, 2 $watches. I'll start hacking chunks out and see what results. Commented May 16, 2016 at 13:12

0

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.