7

Is there a way to load a single entity of a Backbone collection (from the server)?

Backbone.Collection.extend({
  url: '/rest/product'
});

The following code can load the entire collection with a collection.fetch() but how to load a single model? Backbone's documentation says clearly that GET can be done /collection[/id] but not how.

yves amsellem
  • 7,106
  • 5
  • 44
  • 68

6 Answers6

9

The model has to be declared that way:

Backbone.Model.extend({
  url: function() {
    return '/rest/product/'+this.id;
  }
});

Using it is simple as:

var model = new ProductModel();
model.id = productId;
model.fetch({ success: function(data) { alert(JSON.stringify(data))}});
yves amsellem
  • 7,106
  • 5
  • 44
  • 68
  • Are you sure it's ok to use `model.id = productId` instead of `model.set('id', productId)`? – SimplGy May 23 '13 at 17:22
  • Yep, sure. The model uses this.id which is not a backbone attributes. Using model.set('id', ..) requires to use model.get('id') in his proper class. Both works, mine won't interfere with the backbone model attributes :D – yves amsellem May 24 '13 at 08:43
7

While we set

url:"api/user" 

for the collection, the equivalent for the model is

urlRoot:"api/user"

this will make backbone automatically append the /id when you fetch()

j040p3d20
  • 350
  • 4
  • 7
4

collection.fetch( {data: { id:56 } } )

Jason Plank
  • 2,336
  • 5
  • 31
  • 40
Álvaro García
  • 431
  • 2
  • 7
  • Works as expected +1. But it gives me error after the execution of above line. `Uncaught TypeError: object is not a function `. Can you help? – Shubh Dec 01 '13 at 18:38
1

I did this:

Catalog.Categories.Collection = Backbone.Collection.extend({
fetchOne : function (id, success) {
    var result = this.get(id);
    if (typeof result !== 'undefined') {
        console.log(result, 'result')
        success.apply(result);
        return;
    }
    var where = {};
    where[this.model.prototype.idAttribute] = id;
    var model = new this.model(where);
    this.add(model);
    console.log(this._idAttr, where, this.model)
    model.fetch({success: function () {
        success.apply(model);
    }});
}
};

Now call it:

collection.fetchOne(id, function () {console.log(this)});

No more guessing if the model is already in the collection!. However, you have to use a call back as you can't depend on an intimidate result. You could use async false to get around this limitation.

Fatmuemoo
  • 2,187
  • 3
  • 17
  • 34
0

just .fetch a Model.

So create a model with it's own .url function.

Something like

function url() {
  return "/test/product/" + this.id;
}
Raynos
  • 166,823
  • 56
  • 351
  • 396
0

I did this:

var Product = Backbone.Model.extend({});
var Products = Backbone.Collection.extend({
  model: Product,
  url: '/rest/product'
});
var products = new Products();
var first = new Product({id:1});
first.collection = products;
first.fetch();

This has the advantage of working when you're not using a REST storage engine (instead, using something like the HTML5 Local storage, or so forth)

Adam Ness
  • 6,224
  • 4
  • 27
  • 39