Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone.js fetch collection from it's initialize method

someone building an app for us, provided me the code so I could go through it, and I noticed this, which at first seems OK, and even nice to let the collection manage his data but after a while I started thinking about the possible pitfalls in this idea

so: is it good practice to fetch a collection's data from it's own initialize method.

for example:

var Book = Backbone.Model.extend({});

var Books = Backbone.Collection.extend({

    url: '/books',

    initialize: function(){
        // do some logic here

        // if collection is empty, fetch from server
        if(this.size() == 0)
            this.fetch();
    }

});

i ask this because i feel it might be a problem in the following situation:

suppose we are in a routeAction:

books: function() {
    var books = new Books();
    var bookList = new BookList({ collection: books });
}

isn't this situation possible failure, if the fetch would be faster than the initialization of the view, where the view would have bound to a reset event, the reset would have triggered way before the initialize of the view had been executed?

am I wrong on this, or should I submit a ticket to get this fixed.

like image 553
Sander Avatar asked Mar 07 '12 14:03

Sander


1 Answers

While in practice the initialization of the view will most likely occur before fetch() is complete (and you would bind render() to reset not initialize()) it's a really bad idea to rely on the order of async operations anyway. In other words, your code should be written in a way that makes order irrelevant.

I have seen fetch() being called in initialize() in various projects. I still think it's undesirable and bad practice. Explicitly fetching when you need to also has these advantages:

  1. You can do it when you need to, not every time you create a new collection.
  2. You can do certain things in order if you want to:

    For example, you can initialize your view and render only once you have fetched.

    var bookList, books = new Books();
    var p = books.fetch();
    p.done(function () {
      bookList = new BookList({collection: books });
      bookList.render();
    });
    
  3. It makes testing easier.

like image 106
ggozad Avatar answered Oct 01 '22 22:10

ggozad