0

Hi guys I am new to Angular so please be easy. I noticed that when I tried deleting an object from an array passed into a function, it would delete the object from the array within the function, but not in the original array. It confused me because I thought they were passed by reference:

function controller($scope, $http) {
    var vm = this;
    vm.breakfast = [ { id:1, 'name':'fruit' }, { id:2, 'name':'egg' } ];

    function removeFromMeal(meal, entryId) {
        meal = meal.filter (function (entry) {
           return entry['id'] !== entryId;
        }
    }

    function manageEntry(entry) {
        ...
       // Condition to remove meal from vm.breakfast
       if (...) { removeFromMeal(vm.breakfast, entry['id']); }
    }
}

The issue is, if I pass an entry with an id of 1 into manageEntryand set breakpoints within removeFromMeal, I can see that the 'meal' array is successfully being filtered (i.e. object with id 1 is removed from vm.breakfast). However, as soon as that function returns, it(vm.breakfast) is exactly the same as if the function never ran. I'm sure the issue is with context/scope, would the use of $apply be apt here somewhere?

Thanks in advance.

1
  • 1
    To remove something from an array you need to use delete or array.splice(). I don't see anything like that. array.filter returns a new array, it doesn't modify the given array. Commented Mar 7, 2016 at 17:40

3 Answers 3

1

meal.filter() returns a new array, it doesn't modify the original array. And assigning to the meal variable just modifies the local variable, it doesn't modify the variable or object that was used when calling the function. Javascript functions are called by value, where the value can be a reference to an array or object, but it's not a reference to the location where the object came from. You need to write:

if (...) { vm.breakfast = removeFromMeal(vm.breakfast, entry['id']); }
Sign up to request clarification or add additional context in comments.

1 Comment

Ahh, interesting. Thank you!
0

You can work about copy.

function manageEntry(entry) {
    ...
   // Condition to remove meal from vm.breakfast
   if (...) { removeFromMeal(angular.copy(vm.breakfast), entry['id']); }
}

I hope that will help you

Comments

0

Consider using splice instead. That will remove the value from the existing array.

angular.module('app', []).controller('MyController', function($scope) {
  var vm = this;
  vm.manageEntry = manageEntry;
  vm.breakfast = [{
    id: 1,
    'name': 'fruit'
  }, {
    id: 2,
    'name': 'egg'
  }];

  function removeFromMeal(meal, entryId) {
    for (var i = 0; i < meal.length; i++) {
      var entry = meal[i];
      if (entry['id'] === entryId) {
        //Using splice, remove the item at index i from the meal
        meal.splice(i, 1);
        return;
      }
    }
  }

  function manageEntry(entry) {
    // Condition to remove meal from vm.breakfast
    if (true) {
      removeFromMeal(vm.breakfast, entry['id']);
    }
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<div ng-app="app">
  <div ng-controller="MyController as vm">
    <ul>
      <li ng-repeat="entry in vm.breakfast">
        {{entry.name}}
        <button ng-click="vm.manageEntry(entry)">Manage {{entry.name}}</button>
      </li>
    </ul>

  </div>
</div>

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.