hyprstack
hyprstack

Reputation: 4228

backbone collection url does not take parameters

I have a Backbone Collection class with the url property set to a method.

The url is comprised of 3 "elements" which I have called baseUrl, username and path - so it would look something like baseUrl/username/path

I use the same instance for several users in the spa I am working on. However the one element I want to be able to change (after instantiation) is the username. I need this for 2 reasons.

1st - I don't have the username property at instantiation time.

2nd - The username changes depending on the user and I don't want to create new instances of the collection for every new user.

So my issue is why does the url method not take parameters after instantiating the collection so that I could do something like myCollection.url({username: "Mac"})?

Also why does Backbone not allow for parameters to be passed into the url method?

Upvotes: 1

Views: 344

Answers (1)

Emile Bergeron
Emile Bergeron

Reputation: 17430

Backbone calls the url method with the collection as the context, so you can access member variables of your collection instance with this.

var MyCollection = Backbone.Collection.extend({
    url: function() {
        return "base-url/" + this.username + "/path";
    },
});

To use this after instanciation, you could set the username field of your collection manually or you could override the sync method of your collection.

var MyCollection = Backbone.Collection.extend({
    url: function() {
        return "base-url/" + this.username + "/path";
    },

    sync: function(method, model, options) {
        options = options || {};
        if (options.username) this.username = options.username;

        // call the default sync
        return Backbone.collection.prototype.sync.call(this, method, model, options);
    }
});

And use it:

myCollection.fetch({ username: "Mac" });

Additional information on how to know how url is called

I'm an avid user of the annotated source of Backbone and it's really important as a lot of Backbone's features are undocumented and the sources are small and easy to go through.

If you check the sync method, you should see that line:

params.url = _.result(model, 'url') || urlError();

And if you check the underscore's result function, you can see that it calls the function (passed as a string) like this:

return _.isFunction(value) ? value.call(object) : value;

Upvotes: 1

Related Questions