Bind to error event of a model created by collection.create()?
-
22-03-2021 - |
Question
I have a collection of Comments and a view which is used to create new comments. Each comment has some client side validation going on:
class Designer.Models.Comment extends Backbone.Model
validate: (attrs) ->
errors = []
# require presence of the body attribte
if _.isEmpty attrs.body
errors.push {"body":["can't be blank"]}
unless _.isEmpty errors
errors
The Comments collection is super simple:
class Designer.Collections.Comments extends Backbone.Collection
model: Designer.Models.Comment
I create comments in the NewComment
view. This view has access to the comments collection and uses it to create
new comments. However, validations fails in the Comment
model don't seem to bubble up through the collection. Is there a batter way to do this?
class Designer.Views.NewComment extends Backbone.View
events:
'submit .new_comment' : 'handleSubmit'
initialize: ->
# this is where the problem is. I'm trying to bind to error events
# in the model created by the collection
@collection.bind 'error', @handleError
handleSubmit: (e) ->
e.preventDefault()
$newComment = this.$('#comment_body')
# this does fail (doesn't hit the server) if I try to create a comment with a blank 'body'
if @collection.create { body: $newComment.val() }
$newComment.val ''
this
# this never gets called
handleError: (model, errors) =>
console.log "Error registered", args
Solution
The problem is that the collection event that aggregates all of the model events hasn't been hooked up yet. That hookup happens in the _add()
function. Since the validation fails before the model gets added, you don't get the event.
The only indication of failure happens when create
returns false but it looks like you've figured that out already.
If you need the validation errors, you will need to come up with a way to get the errors to you.
One way would be to fire off an EventAggregator message inside the validator. The other would be to circumvent or re-define the Collection.create
function to hook the error event on the model.
Something like this?
model = new Designer.Models.Comment()
model.bind "error", @handleError
if model.set body: $newComment.val()
model.save success: -> @collection.add(model)