Backbone.js: Elegant way to check if data ready and if the dataset is empty

backbone.js, javascript

Solution

If you don't like listening for `reset`, you can pass a callback directly to `.fetch()`:

BasicDealList.fetch({
    success: function(collection, response){
        // ...
    }
});

If, later in your app, you want to know whether you've fetched the data already, you could usually just check `BasicDealList.length`. If you want to avoid making repeated requests for collections that are actually empty on the server, you'll probably need to work out a custom solution, e.g. setting a flag on `.fetch()`:

BasicDealList.fetch({
    success: function(collection, response){
        BasicDealList.fetched = true;
        // ...
    }
});

As for the empty data issue, you should be returning `[]` from the server instead of `{}`. Backbone's Collection calls `this.add(models, ...)` within `.reset()`, and `.add()` checks whether the `models` argument is an array; if it's not, it wraps it in one:

models = _.isArray(models) ? models.slice() : [models];

So passing `{}` will result in `models` set to `[{}]`, which is not what you want. If you can't control the server, you could do the check for `{}` in a custom `.parse()` method, returning `[]` if it's found.

Problem

I'm looking for a better solution for two things: How can I understand if the data is fetched and ready, I use `BasicDealList.on("reset", function(){})` to understand if the data is fetched from ajax and parsed and ready to be used but it feels dirty. If an empty JSON comes from fetching such as `{}`, it still shows BasicDealList.length as 1 while it should be 0 thus I was forced to check if the first element is empty via `collection.length == 1 && jQuery.isEmptyObject(BasicDealList.toJSON()[0]` which is very ugly. Here is the code: ``` BasicDeal = Backbone.Model.extend(); BasicDealCollection = Backbone.Collection.extend({ model: BasicDeal, url: '/some/ajax/url/', }); BasicDealList = new BasicDealCollection(); BasicDealList.on("reset", function(collection, response){ isEmpty = collection.length == 1 && jQuery.isEmptyObject(BasicDealList.toJSON()[0]); if (isEmpty){ // render no deal found html } else{ // render list of deals } } BasicDealList.fetch(); ```

Original source