Backbone collection setting default API url using RequireJS

How can I set a default url/server for all my requests from collections and models in Backbone?

Example collection:

define([
    'backbone',
    '../models/communityModel'
], function(Backbone, CommunityModel){
    return Backbone.Collection.extend({
        url: '/communities', // localhost/communities should be api.local/communities
        model: CommunityModel,
        initialize: function () {
            // something
        }
    });
});

I make an initial AJAX call to get my settings including the url of the API (api.local).

How can I reroute the requests without passing it to all my models or hardcoding the url in the models and collections?

Answers:

Answer

your url takes a string or a function.

with your settings ajax call you can store it in a proper location, and go fetch that from the function

to use your example: suppose your ajax call, saved the url in a myApp.Settings.DefaultURL

define([
    'backbone',
    '../models/communityModel'
], function(Backbone, CommunityModel){
    return Backbone.Collection.extend({
        url: function(){
            return myApp.Settings.DefaultURL + '/communities';
        }, 
        model: CommunityModel,
        initialize: function () {
            // something
        }
    });
});

remark make sure this url is somehow caught or handled when it would be fired before your settings are set, if your initial ajax call fails or takes its time, your app might already be started without it's settings set, should one use a model.save() at that point, you would need to handle this.

Answer

By over-riding (but not over-writing) the Backbone.sync method you can achieve the same result without having to add the same code to every single model/collection.

define(['underscore', 'backbone', 'myApp'], function (_, Backbone, myApp) {
    'use strict';

    // Store the original version of Backbone.sync
    var backboneSync = Backbone.sync;

    // Create a new version of Backbone.sync which calls the stored version after a few changes
    Backbone.sync = function (method, model, options) {
        /*
         * Change the `url` property of options to begin with the URL from settings
         * This works because the options object gets sent as the jQuery ajax options, which
         * includes the `url` property
         */
        options.url = myApp.Settings.DefaultURL + _.isFunction(model.url) ? model.url() : model.url;

        // Call the stored original Backbone.sync method with the new url property
        backboneSync(method, model, options);
    };
});

Then in your model/collection you can just declare the url as usual (e.g. url: '/events)

Don't forget to require the file with the new Backbone.sync code somewhere.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.