Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular scope doesn't update when removing an item

I have a simple application where I can add users to a list and remove them.

The form to add a new user binds to $scope.newPerson. On submitting the form, I add the newPerson object to $scope.people which is an array containing person objects.

I loop over the people array with an ng-repeat directive, to print out the people who are currently added to the scope. These rows all have a remove button (Jade snippet):

div.row(data-person, ng-repeat="person in people", ng-model="person")
    button(ng-click="removePerson(person)") Remove

When I click the Remove button, I execute this function:

$scope.removePerson = function(person) {
  var index = $scope.people.indexOf(person);
  if (index > -1) {
    $scope.people.splice(index, 1);
    person = null;
  }
}

This removes the row from the table, and sets the person scope to null. Batarang shows { This scope has no models } afterwards.

However, I have noticed that my people array doesn't update. When I check it's scope in Batarang, the person I just deleted is still in that array. When I start typing to add a new person, it updates. If I submit the whole page to my server without doing this, the array still contains the removed people.

If i put $scope.$apply() after person = null;, I get the expected behaviour, however it throws an error that an apply is in progress. I also read calling $apply() yourself is considered bad practice. (?)

I'm new to Angular and I can't seem to find a lot of information about solving this problem. How would I make it update my array when I remove a person? Thanks.

like image 374
Joris Ooms Avatar asked Nov 11 '22 17:11

Joris Ooms


1 Answers

I did the following to fix this:

No more ng-model on the ng-repeat block:

div.row(data-person, ng-repeat="person in people")

Refactored the ng-click event for removePerson():

<button ng-click="removePerson($index)">
    Remove
</button>

and changed the removePerson() code to this:

$scope.removePerson = function(index) {
  $scope.people.splice(index, 1);
};

Not sure if this actually fixed anything compared to my previous code, because I noticed that this was also a Batarang issue. When I simply log {{ people }} to my HTML, or console.log($scope.people), I see the people array update. However, in Batarang, the array does not update.

Lesson learned: sometimes, logging stuff out yourself is better than relying on tools ;)

like image 131
Joris Ooms Avatar answered Nov 15 '22 04:11

Joris Ooms