How to handle multiple invalid events being fired from collection.create() in backbone.js
I am adding a model using the collection.create method. I have over-ridden the model.validate method and the error window pops up I get the correct error messages.
Everything seems to work great until I click the save button a third of fourth time. The invalid event gets fired for every previous invalid model. I noticed the collection did not clean up after itself when the invalid event fired so I added the line model.collection.pop() hoping that would solve it.
The invalid event is still fired off n number of times. N being the number of times I have attempted to create a new model until I reload the app. I found that I should only display the error message if the model being passed in has a collection object on it. And now everything works but this seems a bit janky.
I tried adding model.stopListening() inside the invalid event method. No luck though. I assume this has something to do with me not completely cleaning up these partial or invalid models.
createNewAsset: (event) -> @collection.on "invalid", (model, error) => console.log "invalid fired" unless model.collection is undefined errView = new MyApp.Views.Error(collection: error) $("body").append(errView.render().el) model.collection.pop() @collection.on "sync", -> Backbone.history.navigate("assets", true) @collection.create name: @$el.find("#new_asset_name").val()
The above code works for the end user, but I have some zombie models or collections firing off n number of events. N being the number of times the user has clicked the save button.
I don't think your problem is that you have stray models, your problem is that you're binding a new anonymous "invalid" callback to the collection every time createNewAsset is called.
You should just bind your "invalid" and "sync" handlers once in initialize:
initialize: -> # You could still use anonymous functions here. @listenTo(@collection, 'invalid', @bad_model) @listenTo(@collection, 'sync', @synced) #... bad_model: (model, error) -> console.log('invalid fired') #... synced: -> Backbone.history.navigate('assets', true)
And then your createNewAsset becomes simply this:
createNewAsset: (event) -> @collection.create name: @$('#new_asset_name').val()
I also switched your @$el.find() to @$() which is a standard built in short cut for @$el.find.