Search code examples
javascriptbackbone.jsmarionettetastypiebackbone.paginator

Backbone.Paginator in 'infinite' mode throws 'Maximum call stack size exceeded' on model.destroy


I'm completely stuck on this one and can't figure out exactly why this is happening. I'm using Backbone.Paginator within a Marionette application. Also, for the API I'm using Tastypie, which shouldn't matter, but I want to be as thorough in my explanation as possible.

First, I have defined a pageable collection:

 Entities.SimCollection = Backbone.PageableCollection.extend({
   url: "api/sims/response/",

   mode: "infinite",

   state: {
     pageSize: null,
     sortKey: "updated",
     order: 1
   },

   queryParams: {
     totalPages: null,
     totalRecords: null,
     currentPage: null,
     sortKey: "sort",
     order: "direction",
     directions: {
       "1": "asc",
       "-1": "desc"
     }
   },

   parseRecords: function(resp) {
     return resp.objects;
   },

   parseLinks: function (resp, xhr) {
     return resp.meta;
   },

   model: Entities.Sim

 });

And when I go to destroy a model through my view utlizing this code:

  simsListView.on("itemview:sim:delete", function(childView, args){
    args.model.destroy();
  });

I then get a: Uncaught RangeError: Maximum call stack size exceeded, and if the console in chrome is open, the browser just completely crashes.

The only thing I was able to figure out to get it to stop throwing the error was to do something that involved switching the mode from 'infinite' to 'server', but that just seems completely wrong and it also loses its state and goes back to the first page if I delete a model on any other page:

          simsListView.on("itemview:sim:delete", function(childView, a
rgs){
            sims.switchMode("server");
            args.model.destroy();
          });

Of course, any help is greatly appreciated.

Additional Information:

In my Layout(ItemView) I am doing something like this:

  Sim.SimView = Marionette.Layout.extend({
    initialize: function(options) {
      this.userModel = options.userModel;
    },
    triggers: {
      "click td a.js-edit": "sim:edit",
      "click button.js-view": "sim:view"
    },
    tagName: "tr",
    template: "#sims-item",
    behaviors: {
      Confirmable: {
        event: "sim:delete",
        message: "Are you sure you want to delete this SIM?"
      }
    },
    regions: {
      editRegion: "#edit-region",
      deleteRegion: "#delete-region"
    }
  });

Which is using a Marionette Behavior to alert the user for confirmation before deleting the item.


Solution

  • So, I figured this out - they key here, at least for me, was in the delete method, which was originally:

              simsListView.on("itemview:sim:delete", function(childView, args){
                sims.switchMode("server");
                args.model.destroy();
              });
    

    Caused the 'Maximum call stack exceed' - the solution is to modify it so that, first it's not switching to 'server' mode, but stays in 'infinite' mode, and also, I needed to remove the model from the full collection and then destroy it - that seems to be the solution:

              simsListView.on("itemview:sim:delete", function(childView, args) {
                sims.fullCollection.remove(args.model);
                args.model.destroy();
              });
    

    If anyone comes up with a specific reason for this, I'd be interested to hear it, but otherwise problem solved!