Search code examples
javascriptbackbone.jspaginationrendr

Backbone - Populating multiple models from one fetch call in my controller


Say I have a collection (of search results, for example) which needs to be populated and a pagination model that needs to take values for current page, total number of pages, etc. In my controller, I make a GET call to an API which returns both search results and pagination information. How, then, can I fetch all this information and parse it into a collection and a separate model? Is this possible?

I am using AirBNB's Rendr, which allows you to use a uniform code base to run Backbone on both the server and the client. Rendr forces me to parse the API response as an array of models, keeping me from being able to access pagination information.

In Rendr, my controller would look like this:

module.exports = {
    index: function (params, callback) {
        var spec = {
            pagination: { model: 'Pagination', params: params },
            collection: { collection: 'SearchResults', params: params }
        };
        this.app.fetch(spec, function (err, result) {
            callback(err, result);
        });
    }
}

I apologize if this is not clear enough. Feel free to ask for more information!


Solution

  • This is super old so you've probably figured it out by now (or abandoned it). This is as much a backbone question as a Rendr one since the API response is non-standard.

    Backbone suggests that if you have a non-standard API response then you need to override the parse method for your exact data format.

    If you really want to break it up, the way you may want to code it is:

    • a Pagination Model
    • a Search Results Collection
    • a Search Result Model
    • and most importantly a Search Model with a custom parse function

    Controller:

    index: function (params, callback) {
        var spec = {
            model: { model: 'Search', params: params }
        };
        this.app.fetch(spec, function (err, result) {
            callback(err, result);
        });
    }
    

    Search Model

    var Base = require('./base'),
        _ = require('underscore');
    
    module.exports = Base.extend({
        url: '/api/search',
        parse: function(data) {
            if (_.isObject(data.paginationInfo)) {
                data.paginationInfo = this.app.modelUtils.getModel('PaginationInfo', data.paginationInfo, {
                    app: this.app
                });
            }
            if (_.isArray(data.results)) {
                data.results = this.app.modelUtils.getCollection('SearchResults', data.results, {
                    app: this.app,
                    params: {
                        searchQuery: data.searchQuery // replace with real parameters for client-side caching.
                    }
                });
            }
            return data;
        }
    });
    module.exports.id = 'Search';