From 7699cee888a0aa5744ccfa2d9e2bb6b3c1cdf03c Mon Sep 17 00:00:00 2001 From: Paul Falgout Date: Tue, 3 Oct 2017 00:35:29 +0900 Subject: [PATCH] Prevent error when removing a model that does not match a view (#3472) Resolves https://github.com/marionettejs/backbone.marionette/issues/3445 If using `buildChildView` to build views that aren't given the collection's model, when the model is removed it would throw errors when other methods expected views to exist. --- src/next-collection-view.js | 10 +++++++-- .../collection-view-data.spec.js | 22 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/next-collection-view.js b/src/next-collection-view.js index 21d42544bc..1e6d67860a 100644 --- a/src/next-collection-view.js +++ b/src/next-collection-view.js @@ -131,13 +131,19 @@ const CollectionView = Backbone.View.extend({ }, _removeChildModels(models) { - return _.map(models, _.bind(this._removeChildModel, this)); + return _.reduce(models, (views, model) => { + const removeView = this._removeChildModel(model); + + if (removeView) { views.push(removeView); } + + return views; + }, []); }, _removeChildModel(model) { const view = this.children.findByModel(model); - this._removeChild(view); + if (view) { this._removeChild(view); } return view; }, diff --git a/test/unit/next-collection-view/collection-view-data.spec.js b/test/unit/next-collection-view/collection-view-data.spec.js index d3a0c72253..7cc60b797b 100644 --- a/test/unit/next-collection-view/collection-view-data.spec.js +++ b/test/unit/next-collection-view/collection-view-data.spec.js @@ -251,4 +251,26 @@ describe('next CollectionView Data', function() { expect(myCollectionView.$el.children()).to.have.lengthOf(2); }); }); + + describe('when removing a model that does not match a children view model', function() { + let myCollectionView; + let collection; + + beforeEach(function() { + collection = new Backbone.Collection([{ id: 1 }, { id: 2 }, { id: 3 }]); + + const BuildCollectionView = MyCollectionView.extend({ + buildChildView(child, ChildViewClass) { + return new ChildViewClass({ model: new Backbone.Model() }); + } + }); + + myCollectionView = new BuildCollectionView({ collection }); + myCollectionView.render(); + }); + + it('should not throw an error', function() { + expect(collection.remove({ id: 1 })).to.not.throw; + }); + }); });