Running Turtle
Running Turtle

Reputation: 12752

How to set a Collection's url

let's say I have :

var Book = Backbone.Model.extend();

var Collection = Backbone.Collection.extend({
  model: Book,
  url: '/books',
  initialize: function(){
    this.fetch();
  })
})

How can I change the Collection's url when instantiating a new collection ?

var AdventureBooks = new Books({ url: '/books/adventure' }) does not work

var AdventureBooks = new Books({ category: 'adventure' })

and in the Collection definition:

url : '/books/' + this.category does not work either.

Thanks.

Upvotes: 35

Views: 41109

Answers (8)

Pavel B
Pavel B

Reputation: 154

This work for me (tested with backbone 1.2.1):

var serverData = Backbone.Collection.extend({
url: function() {
    return '//localhost/rest/' + this.dbname;
},
constructor: function(a) {
    if(a.dbname){
        this.dbname = a.dbname;
    }
    Backbone.Collection.apply(this, arguments);
}
});

use it as follows:

var users = new serverData({dbname : 'users'});

Upvotes: 0

chrisweb
chrisweb

Reputation: 1510

If you want to have dynamic urls for your collection, try this (tested with backbone 1.1.2):

Create an instance of your backbone collection and pass the dynamic url parameter as an option (the options object needs to be the the second argument as the first one is an optional array of models):

var tweetsCollection = new TweetsCollection(null, { userId: 'u123' });

Then inside of your collection, create a dynamic url function that uses the value from the options object:

var TweetsCollection = Backbone.Collection.extend({
    url: function() {
        return '/api/tweets/' + this.options.userId;
    },
    model: TweetModel
});

Upvotes: 3

Pavel Sedek
Pavel Sedek

Reputation: 529

The best solution for me is the initialize method, look at this example:

Entities.MyCollection = Backbone.Collection.extend({
    model: Entities.MyModel,
    initialize: function(models,options) { 
        this.url = (options||{}).url || "defaultURL";
    },
}

use it as follows:

var items = new Entities.MyCollection();                     //default URL
var items = new Entities.MyCollection([],{url:'newURL'});    //changed URL

Upvotes: 2

ckot
ckot

Reputation: 891

I know that this a late reply, but I had a similar although slightly more complicated situation, and the selected answer didn't really help me.

I have a Conditions collection, and each Experiment model has multiple conditions, and I needed my url to be /api/experiments/:experimentId/conditions, but I didn't know how to access the experimentId from the empty Conditions collection.

In my Conditions collection url function, I did a console.log(this.toJSON()) and discovered that Backbone inserts a single dummy model in the empty collection with whatever attributes you passed in at it's creation time.

so:

var Conditions = new ConditionsCollection({
  experimentId: 1
});

I somehow doubt that this would be considered a best practice, hopefully someone else will respond with a better solution, but here's how I defined my Collection:

var ConditionsCollection = Backbone.Collection.extend({
  model: Condition,
  url:  function(){
    var experimentId = this.at(0).get("experimentId");
    return "/api/experiments/" + experimentId + "/conditions";
  }
});

Upvotes: 1

Ruy Diaz
Ruy Diaz

Reputation: 3122

Like Daniel Patz pointed out , the problem lies in how you're instantiating the collection. I just struggled with this for a bit right now, so I thought I'd update this, even though the question is somewhat old.

The first argument is expected to be an array of models, with the options coming after. This should work:

var AdventureBooks = new Books([], { url: '/books/adventure' })

If you want a dynamic URL, then Raynos' answer might be the way to go.

Upvotes: 9

Juha Palomäki
Juha Palomäki

Reputation: 27042

For some reason the parameters passed to Collection constructor (for example "url") are not set to the object. The collection uses only few of those (model and comparator).

If you want to pass the url via constructor you need to create initialize method that copies the necessary parameters to the object:

var Book = Backbone.Model.extend({
    initialize: function(props) { 
        this.url = props.url;
    }
}
var book = new Book({url: "/books/all"});

Upvotes: 13

Raynos
Raynos

Reputation: 169421

var Book = Backbone.Model.extend({
  "url": function() {
    return '/books/' + this.get("category");
  }
});

Upvotes: 28

ponzao
ponzao

Reputation: 20934

The following should work:

var AdventureBooks = new Books();
AdventureBooks.url = '/books/adventure';

Upvotes: 38

Related Questions