10

There's a new behaviour in the latest version of Backbone (1.0.0 in which the reset event is no longer triggered by default after fetching a Collection.

http://backbonejs.org/#changelog

Renamed Collection's "update" to set, for parallelism with the similar model.set(), and contrast with reset. It's now the default updating mechanism after a fetch. If you'd like to continue using "reset", pass {reset: true}.

The problem is that I want to capture the event when the collection has been finally fetched (pretty common case, indeed!)

I could listen to add, remove and change event, but if the collection is empty I don't know how to catch the event.

So, what would be the new, recommended way to catch when the collection request has finalized, or is it passing a { reset = true } the only way to achieve it???

ps: here's the original question, BTW can't catch Backbone Collection reset event

Community
  • 1
  • 1
opensas
  • 60,462
  • 79
  • 252
  • 386

4 Answers4

23

From Backbone.sync doc,

Whenever a model or collection begins a sync with the server, a "request" event is emitted. If the request completes successfully you'll get a "sync" event, and an "error" event if not.

For example,

var C = Backbone.Collection.extend({
    url: '/echo/json/'
});

var c = new C();
c.on('sync', function() {
    console.log('sync');
});
c.fetch();

And a demo http://jsfiddle.net/nikoshr/GLATm/

nikoshr
  • 32,926
  • 33
  • 91
  • 105
10

We can pass a method as a success handler when we call fetch on collection and as you said you just want to do something when everything[add,remove,update or reset] has happened, you can do inside this success handler.

collection.fetch({
  success: function() {
    // Do Something
    // This is called when all add, remove and update operations have been done
  }
});

Note: success handler is always executed irrespective of you have passed reset:true or not. Irrespective of your collection gets empty or not and It will be called at the last step when all the add,remove and update events have occurred.

Let me know if it does not solve your problem.

Sachin Jain
  • 21,353
  • 33
  • 103
  • 168
0

My own solution is indeed pretty simple. I already have a BaseCollection with added features, so in there I just set as default { reset: true }. The code should be something like this (my own BaseCollection has a lot of stuff that is not pertinent here):

var BaseCollection = Backbone.Collection.extend({
  fetch: function(options) {
    options = options || {};
    options.reset = (options.reset === undefined ? true : options.reset);
    // just call super.fetch
    return Backbone.Collection.fetch.call(this, options);
  };
});     
opensas
  • 60,462
  • 79
  • 252
  • 386
0

Using promises...

// you could use promises as well
// P.S.: pardon jquery promises :)

var C = Backbone.Collection.extend({
    url: '/echo/json/'
});

var c = new C();

// c.fetch() returns jqXHR object that you can listen too
$.when( c.fetch() )
   .done(successFn)
   .fail(failFn)
   .always(alwaysFn);
Denis Ivanov
  • 905
  • 10
  • 16