ElderMael
ElderMael

Reputation: 7101

Load Model From More Than One URL

How can I load different attributes for a model using different URLs?

E.g. I have 3 different and independent URLs that will return some attributes and I want to add all of those to a single model, suppose that I have the promise returned by all of them like this:

var model = //...    

$.when(nameAttributes, addressAttributes, metaAttributes).then(
function(nameData, addressData, metaData) {
    return _.extend({}, nameData, addressData, metaData);
})
.done(function(allData) {
    model.set(allData);
    doStuffWith(model);
});

Is there a way to turn that into this:

model.fetch().done(function(){ doStuffWith(model); });

Upvotes: 1

Views: 46

Answers (1)

Javier Buzzi
Javier Buzzi

Reputation: 6808

Well.. Ok, this should do what you want. I STRONGLY suggest you do NOT take this route. Keep the data separately in individual Model()s that way you can update it and pull it when ever you need to. If you take this approach saving data will be a disaster.

http://jsfiddle.net/kjhvwxg4/

PS. I tried to not add any more code then i had to, keep in mind this will probably not handle error handling very well since xhr will never throw an error, you need to catch it yourself -- i didnt want to spend the time coding that since this is just a proof of concept.

var Model1 = Backbone.Model.extend({
    fetch: function(options) {
        options = _.extend({
            parse: true
        }, options);
        var model = this;
        var success = options.success;
        var error = options.error;
        options.success = function(resp) {
            var serverAttrs = options.parse ? model.parse(resp, options) : resp;
            if (!model.set(serverAttrs, options)) return false;
            if (success) success.call(options.context, model, resp, options);
            model.trigger('sync', model, resp, options);
        };
        options.error = function(resp) {
            if (error) error.call(options.context, model, resp, options);
            model.trigger('error', model, resp, options);
        };

        // custom code starts here

        var call1 = $.getJSON('http://jsonplaceholder.typicode.com/posts/1');
        var call2 = $.getJSON('http://jsonplaceholder.typicode.com/comments/2');
        var call3 = $.getJSON('http://jsonplaceholder.typicode.com/albums/3');
        var xhr = $.when(call1, call2, call3);

        // mimics the same triggers the normal backbone does
        model.trigger('request', model, xhr, options);

        xhr.done(function(one, two, three){
            var resp = _.extend(one[0], _.extend(two[0], _.extend(three[0], {})));
            options.success(resp);              
        });

        // we still need to send back an event handler
        return xhr;
    }
});

var model = new Model1();
model.fetch();

model.on('sync', function(model) {
    alert(JSON.stringify(model.toJSON()));
});

Upvotes: 1

Related Questions