How do I fetch a single model in Backbone?

83,678

Solution 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.

Solution 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();

Solution 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

Solution 4

var Person = Backbone.Model.extend({urlRoot : '/person/details'});
var myName = new Person({id: "12345"});
myName.fetch();

As a result you make a Ajax request on the

URL http://[domainName]/person/details/id 

and you have the JSON response back.

Enjoiiii !!!

Share:
83,678
James A. Rosen
Author by

James A. Rosen

Updated on September 25, 2020

Comments

  • James A. Rosen
    James A. Rosen over 3 years

    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?

  • makevoid
    makevoid over 12 years
    There is a way to avoid this as explained in Backbone Model documentation documentcloud.github.com/backbone/#Model-url
  • Roberto Alarcon
    Roberto Alarcon over 12 years
    @makevoid your I could not make work the example you provide in coffee script or the one in the documentation, the Andrew example works, could you provide and example with foo.url(), it always tell me that there's no function url.
  • Ricardo Amores
    Ricardo Amores over 12 years
    Apparently this doesn't work. Don't even makes a call to the server when calling fetch in the model (nor the collection)
  • user14322501
    user14322501 over 11 years
    this is the same solution as @Hernan
  • SimplGy
    SimplGy almost 11 years
    This is good, but sometimes you don't want to reinstantiate the model. If you want to fetch a specific item against the same model, you can do a silent set: currentBook.set('id', 13423, {silent:true}). This works too, but I'm not sure why: currentBook.id = 13423
  • Dingle
    Dingle over 10 years
    This looks fine, but the collection line looks awkward in cases when we don't really need the collection.
  • Steven Devijver
    Steven Devijver almost 10 years
    @makevoid it seems the method you are referring to only works if the model has been created in a collection. Notice the collection in [collection.url]/[id].
  • Muhaimin
    Muhaimin almost 10 years
    i couldn't get this to work: this.model.get('field'). Looks like the model is is created sub object
  • Lambart
    Lambart about 9 years
    @SimplGy that works because model.id is essentially synonymous with model.attributes.id. If you call model.set('id'), Backbone sets model.id to whatever you specified. And model.id is what gets used when creating the model-specific URL.
  • Adrian Bartholomew
    Adrian Bartholomew over 8 years
    You don't know that. Maybe all he requires is one Clock. Suppose I want to present a client with a single Model of a User record? Should he have access to a Collection of all Users too? Sometimes folk just need some advice while trying to keep their usecase private. Just answer.
  • dmi3y
    dmi3y about 8 years
    this.model.bind("change", this.render, this) worked well for me
  • AlexNikolaev94
    AlexNikolaev94 over 7 years
    @makevoid can you please provide a working link? unfortunately, this one is broken for now
  • makevoid
    makevoid over 7 years
    here's the working link (they moved the doc! wow, 5 years passed, geez): backbonejs.org/#Model-url - @StevenDevijver is correct
  • Ulysse BN
    Ulysse BN over 6 years
    is this coffeescript?
  • makevoid
    makevoid over 6 years
    @UlysseBN yes (was year 2011), you can add var statements, {} inside the ()'s for the passed objects and optional ; ad the end of the lines