1

EDIT tl;dr: I would like to only fetch models and add them to the collection that meet some validation criteria. I am able to use the model.validate() method if I am fetching only a single model, but when using collection.fetch(), model.validate() is not called.

I am using the github gist API to make a gist fallery, a la bl.ocks.org. I would only like to display gists that have a "tags" file, so I have a validate method on my Gist Model:

class Gist extends Backbone.Model

  validate: (attrs, options)->
    if attrs.files.hasOwnProperty("tags") is false
      return "no tags file"

  sync: (method, model, options) ->
    options.timeout = 8000
    options.dataType = 'jsonp'
    options.validate = true
    return Backbone.sync(method, model, options)

  defaults: ......
  parse: (data)-> ......

This works correctly when I fetch a single gist from github. However, when I am fetching a collection of gists, this validate method is not fired.

class Gists extends Backbone.Collection

  model: Gist

  sync: (method, model,options) ->
    options || options = {}
    options.timeout = 8000
    options.dataType = 'jsonp'
    options.validate = true
    return Backbone.sync(method, model, options)

  parse: (response) ->
    response.data

  #more methods here, including initialize, comparator, and custom ones

The behavior I have now is that when I am displaying the list of gists, i get thumbnails for gists that do not have the "tags" file (see screenshot below). However, when I click on a thumbnail with an invalid gist, it won't display because there is a validationError returned from the validate method (The gist model'sfetch method is called when a thumbnail is clicked to get additional information from github before it is rendered)

enter image description here

How can I use the model's validate method to make sure the model is not added to the collection via collection.fetch if it doesn't have a tags file?

elsherbini
  • 1,596
  • 13
  • 23
  • Use a parser (parse function) at collection to filter out unwanted model. – Ravi Hamsa Jul 17 '14 at 18:53
  • Thank you, that worked great. I realize now that something more insidious was going on with `backbone-fetch-cache.` On first page load the models were correctly validated, and only on subsequent refreshes were invalid models shown. But useing collection.parse got around that. – elsherbini Jul 17 '14 at 18:59

2 Answers2

0

Ravi Hamsa's suggestion worked beautifully. Here is how I implemented it:

class Gists extends Backbone.Collection

  model: GistModel

  sync: (method, model,options) ->
    options || options = {}
    options.timeout = 8000
    options.dataType = 'jsonp'
    return Backbone.sync(method, model, options)

  parse: (response) ->
    (gist for gist in response.data when gist.files.hasOwnProperty("tags") is true)
elsherbini
  • 1,596
  • 13
  • 23
0

Backbone has a function called parse, that is called when any data is returned from server before backbone bind the content from server to model. You can override this function, something like this.

Model = Backbone.Model.extend({
    parse: function () {
        return {
            id: this.get("id"),
            AnotherThing: this.get("AnotherThing")
        }
    }
});

Take a read here.

http://backbonejs.org/#Model-parse

Hope it helps.

rcarvalho
  • 790
  • 1
  • 4
  • 14