Backbone: Give model.set a parse option

Created on 21 Jun 2013  ·  13Comments  ·  Source: jashkenas/backbone

The collection counterpart of set allows you to provide a "parse" option to run the parser function before processing the collection object. This is handy when you have bootstrap data that you want to build a collection from, as it wont go through the fetch function.

Is there a reason the model object doesn't provide the same option to parallel collection? It seems inconsistent to me that it is omitted.

Edit: Upon further inspection, reset does still respects the parse option.

duplicate

Most helpful comment

I'm actually using model.set(model.parse(data)) right now since the parse option is missing. This would be really nice to have for consistency with collection.reset etc.

All 13 comments

I'd defer to @caseywebdev about the do-ability of this, but I think its certainly reasonable to have API parity between models and collections parsing. Thanks for opening an issue @etler!

Implementation should be pretty straight forward. I think the major question is if there's any reason not to? Also, what would happen when a key val was provided instead of an attribute object?

This sounds good, but the case that will cause a snag at the top of my head is parse with defaults (notice the order of events here). I'd love to see a PR with your implementation thoughts.

Great, I'd love to take a stab at it.

I was actually going to open a ticket for this as well - but then came across #2013... though I'd assume that was before there was a Collection#set.

I agree with @wookiehangover that the API parity would be nice to have, and I've come across cases where it makes sense when using parse to handle nested data (I've just been using model.set(model.parse(data)) as mentioned in the other ticket).

@tgriesser I don't know how I missed that issue! I agree with that discussion for that use case, but I think a more compelling use case is for parsing bootstrapped data (as well as nested parsing, which I'm doing also). I've also been using the same workaround, but as you said, now that there's a Collection#set, there's now also a parity argument as well.

What's the actual use case for needing this?

If you want to call set on an existing a model where the object has nested data that you'd be pulling of the model in parse. I've wanted this functionality on several occasions.

class Book extends Models.Document
   constructor: ->
      @info = new InfoModel()
      @chapters = new ChaptersCollection()
      super

   parse: (attrs, options) ->
      @info.set(attrs.info, options)
      @chapters.set(attrs.chapters, options)
      _.omit(attrs, 'info', 'chapters')

Now you can do this:

book.set({
  title: 'title',
  info: {
    some: data
    someNested: {
        otherData: ...
    }
  },
  chapters: [{...}, {...}]
}, {parse: true});

and it should work... (yes, model.set(model.parse( works, but it's simpler to have the same api for parsing nested data in collections and models)... though with the issue of #2623 it only works so far down.

Anyone have a thought about how this change would work with defaults? And without double-parsing?

To get it to work with defaults, I created an options.defaults, assigned in the initialize function to pass to set, so they could be applied after the parsing step. I don't know if that's a design decision that we would want, but I wasn't able to think of an alternate solution.

Let's move this conversation over to the open PR...

Is there any update on this?

I'm actually using model.set(model.parse(data)) right now since the parse option is missing. This would be really nice to have for consistency with collection.reset etc.

Was this page helpful?
0 / 5 - 0 ratings