Search code examples
javascriptjsonbackbone.js

BackboneJS Hide Model when date has expired


I have a Backbone App where I display a Collection of Models based on JSON data. Inside the JSON data, I have endDate-which gives me the realtime date. It is based on a competition module. What I want to achieve is that if the given date has expired I want to hide (or even maybe remove) the Model from the collection, so that the competition is no longer available.

So far my competition.js, with the Model in the bottom looks like this:

Competition.View = Backbone.View.extend({
    tagName: 'ul',
    template: 'competition',
    initialize: function() {
        this.listenTo(this.model, 'sync', this.render);             
    },
    serialize: function() {
        return this.model.toJSON();
    }
});

Competition.CompetitionModel = Backbone.Model.extend({
    url: function() {
        return App.APIO + '/i/contests';
    },
    comparator: function(item) {
        return item.get('endDate');
    },

    defaults: {
        "data": []
    }
});

Then in my main module, I import the competition.js, and here I fetch the model and render it in specific HTML element (dont know if its necessary to copy/paste it here for my original question):

function (App, Backbone, Competition) {

    var CompetitionOverview = App.module();

    CompetitionOverview.View = Backbone.View.extend({
        template: 'competitionOverview',
        initialize: function(){
            this.render();
        },
        beforeRender: function() {
            var competitionModel = new Competition.CompetitionModel();
            this.insertView('.singleComp', new Competition.View({model: competitionModel}));
            competitionModel.fetch();   
        },

    });

    return CompetitionOverview;
}

So, how can I achieve to hide/remove the Models which dates have expired?

thanks in advance...


Solution

  • You state that you have Collection of Models, but your Competition.CompetitionModel extends Backbone.Model instead of Backbone.Collection. In my answer I assume that CompetitionModel is a Backbone.Collection and not a Backbone.Model.

    That said, I think you have two options:

    1. Check in your render function of Competition.View whether you should actually show something based on the end-date:

      Competition.View = Backbone.View.extend({
          tagName: 'ul',
          template: 'competition',
          initialize: function() {
               this.listenTo(this.model, 'sync', this.render);             
           },
           serialize: function() {
               return this.model.toJSON();
           },
           render: function(){
                //dependending on in which format your date is you might have to convert first. 
                if(this.model.get('endDate') < new Date().getTime()){
                      //render the view
                }
      });
      
    2. Or, and I think this is more clean, you check the date as soon as the data comes in from the server. I think backbone triggers an "add" event on the collection when the collection is fetched from the server. So, again, make your Competition Model a Competition Collection and listen to the add event. Change

      Competition.CompetitionModel = Backbone.Collection.extend({
          initialize: function () {
              this.on("add", checkDate)
          },
          checkDate: function(model, collection, options){
              //again, get the right conversion
              //but here you should compare your end date with the expire date
              if(model.get('endDate') < new Date().getTime()){
                  this.remove(model.id);
              }
          },
          url: function () {
              return App.APIO + '/i/contests';
          },
          comparator: function (item) {
              return item.get('endDate');
          },
      
          defaults: {
              "data": []
          }
      });