Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ember.js removeObject in forEach not removing all Objects

I am trying to iterate over an array in Ember and remove objects from the array with removeObject(). The example below only removes some objects from the array. I would expect it to iterate over all objects and then remove them:

App = Ember.Application.create();

App.ITEM_FIXUTRES = [
  'Item 1',
  'Item 2'
];

App.ITEM_FIXTURES = App.ITEM_FIXUTRES.map(function (item) {
  return Ember.Object.create({title: item});
});

App.IndexRoute = Ember.Route.extend({
  model: function() {
    return App.ITEM_FIXTURES;
  },

  actions: {
    add: function(title) {
      var items = this.modelFor('index');
      items.addObject(Ember.Object.create({title: title}));

      this.controller.set('title', '');
    },
    removeAll: function() {
      var items = this.modelFor('index');

      items.forEach(function (item) {
        // I actually only want to remove certain objects with specific
        // properties but this illustrates the issue.
        items.removeObject(item);
      });
    }
  }
});

The template is fairly straightforward:

<script type="text/x-handlebars" id="index">
  <h4>Collection List</h4>

  <button {{action 'removeAll'}}>Remove All</button>

  <ul>
    {{#each}}
      <li>{{title}}</li>
    {{/each}}

    <li>{{input type='text' value=title action='add'}}</li>
  </ul>
</script>

Here is a JSBin: http://jsbin.com/kelinime/4/edit

like image 564
mschoening Avatar asked May 05 '14 17:05

mschoening


1 Answers

Snappie above is correct, you shouldn't modify a collection you're iterating. You would create a copy of the collection, then iterate that.

removeAll: function() {
  var items = this.modelFor('index'),
      list = items.toArray();

  list.forEach(function (item) {
    // I actually only want to remove certain objects with specific
    // properties but this illustrates the issue.
    items.removeObject(item);
  });
}

http://jsbin.com/kelinime/7/edit

I realize you say you aren't trying to delete all, but you can also call removeObjects with a list of objects and let Ember handle the iterating. Additionally if the case comes up, you can remove by index also, by using removeAt.

removeAll: function() {
  var items = this.modelFor('index'),
      list = items.toArray();
  items.removeObjects(list);
}

http://jsbin.com/kelinime/8/edit

like image 146
Kingpin2k Avatar answered Oct 19 '22 13:10

Kingpin2k