Friday, May 4, 2012

How do I fetch a single model in Backbone?


I have a Clock model in Backbone:




var Clock = Backbone.Model.extend({});



I'm trying to get an instance of that that has the latest information from /clocks/123 . Some things I've tried:



a "class"-level method




Clock.fetch(123)
// TypeError: Object function (){ ... } has no method 'fetch'



creating an instance and then calling fetch on it:




c = new Clock({id: 123})
c.fetch()
// Error: A 'url' property or function must be specified



a collection



I tried creating an AllClocks collection resource (even though I have no use for such a thing on the page):




var AllClocks = Backbone.Collection.extend({
model: Clock,
url: '/clocks/'
});
var allClocks = new AllClocks();
allClocks.fetch(123);
// returns everything from /clocks/



How do I just get one API-backed Clock?


Source: Tips4all

4 comments:

  1. Your second approach is the approach I have used. Try adding the following to your Clock model:

    url : function() {
    var base = 'clocks';
    if (this.isNew()) return base;
    return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + this.id;
    },


    This approach assumes that you have implemented controllers with the hashbang in your URL like so, http://www.mydomain.com/#clocks/123 , but it should work even if you haven't yet.

    ReplyDelete
  2. Try specifying urlRoot in the model:

    From the docs:

    var Book = Backbone.Model.extend({urlRoot : '/books'});
    var solaris = new Book({id: "1083-lem-solaris"});
    solaris.fetch();

    ReplyDelete
  3. I personally recommend, following the Model#url method documentation

    model = new Model(id: 1)
    view = new View(model: model)
    collection = new Collection([model])
    model.fetch()


    in your collection remember to add the collection url:

    url: "/models"


    and in your View's initialize function do:

    this.model.bind("change", this.render)


    this way backbone will do an ajax request using this url:

    "/models/1"


    your model will be updated and the view rendered, without modifying Collection#url or Model#urlRoot

    note:
    sorry this example came out in coffee script, but you can easily translate it to js adding var statements

    ReplyDelete
  4. Have you tried calling .get(id) on the AllClocks collection?

    ReplyDelete