Search code examples
javascriptbackbone.jsbackbone-routingbackbone.js-collectionsbackbone-model

Fetching different set of models using same type of collection in Backbone


I have a server response that returns the user's id, email, and an array of poll ids that belong to this user. I am trying to get the text of all of the polls belonging to a particular user. I tried passing ajax options to the fetch call, but all of the polls get fetched, not just this user's polls.

Polls is the collection of all polls from all users. A user has to be able to fetch all polls, regardless of which user they belong to (which works fine) and he should also be able to only fetch the polls that belong to them.

API for getting all polls from all users: /api/polls

API for getting a single poll: /api/polls/:poll_id

Is it possible to fetch multiple Backbone models by their ids without having to do a separate fetch request for each of them?

 var polls = new Polls();
 polls.fetch({
     traditional: true,
     data: {
         poll_ids: idsArr
     }
 });

 Background Code:
     var UserSchema = new Schema({
         name: String,
         email: {
             type: String,
             required: true,
             index: {
                 unique: true
             }
         },
         polls: [{
             type: Schema.Types.ObjectId,
             ref: 'Poll'
         }]
     });

 var PollSchema = new Schema({
     name: String,
     options: [{
         text: String
     }]
 });

Solution

  • If I understood correctly, you need one more API like this : /api/:user_id/polls/ which returns the polls related to specific user.

    Create one polls collection globally that points to /api/polls and another one inside the user model that points to /api/:user_id/polls/

    var Poll = Backbone.Model.extend({
      urlRoot: '/api/polls'
    });
    var Polls = Backbone.Collection.extend({
      model: Poll
    });
    var User = Backbone.Model.extend({
      initialize: function() {},
      parse: function(response) {
        this.polls = new Polls(response.usersPolls, {
          url: '/api/'+ this.id +'/polls/'
        });
        /*remove polls info if not needed*/
        return response;
      }
    });
    var allPolls = new Polls(null, {url:'/api/polls/'})
    

    The collection inside user model will fetch the polls related to user, and the other one will have all the polls.

    You should set the urlRoot property of the poll models to /api/polls/ so that their url will be formed correctly like /api/polls/:poll_id rather than /api/:user_id/polls/:poll_id within the user specific polls collection


    Another option would be to handle this entirely at client side by having single collection that fetches all the polls which has a method that accepts a user id and filters itself based on the id.

    But in this scenario you'll either have to cache the polls before filtering, or fetch all the polls again when you need them after applying a filter.