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.

Community
  • 1
  • 1
  • do you want to descending by orderBy:'-PERCENT' – Jahirul Islam Bhuiyan May 13 '16 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. – John Grinsell May 13 '16 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? – sourdoughdetzel May 14 '16 at 00: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. – Saad May 14 '16 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. – John Grinsell May 16 '16 at 13:12
  • Sure, after I post, I find a possible duplicate: http://stackoverflow.com/questions/15475601/angularjs-ng-repeat-list-is-not-updated-when-a-model-element-is-spliced-from-t – John Grinsell May 16 '16 at 13:21

0 Answers0