Finding out when an array of records is fully loaded in Ember.js

by Kasper Tidemann

If you have an array of records fetched from the server, how can you tell when all records have been fully loaded? A simple question, yet the immediate answer is confusing. Let’s dig a bit deeper:

Say you fetch an array of records from the server using Ember Data like so: var fruits = App.Fruit.find(). Now you want to figure out when all the records contained in the fruits array are fully loaded in order to make the UI react or whatever your use case is.

Running the above will return an instance of DS.RecordArray. Hence, calling fruits.get('isLoaded') should do the trick, right? Well, no, since it does not take each individual record into consideration. Instead, it can be achieved using a computed property. Consider this code:

App.FruitController = Em.Controller.extend({
  fruitsLoaded: (function() {
    var fully_loaded = true;
    var fruits = this.get('content');

    if (fruits) {
      fruits.forEach(function(fruit) {
        if (fully_loaded) {
          fully_loaded = fruit.get('isLoaded');
        }
      });
    }

    return fully_loaded;
  }).property('content.@each.isLoaded')
});

The gist of the above is to set the content of an ArrayController to the result of the call to App.Fruit.find() (in a route, preferably) and then listen for changes to the isLoaded property on each of the records contained in the content proxy.

But to be fair, the above is a bit verbose. Building on a previous post, let’s make use of the findProperty function instead. Now, consider this code:

App.FruitController = Em.Controller.extend({
  fruitsLoaded: (function() {
    return !this.get('content').findProperty('isLoaded', false);
  }).property('content.@each.isLoaded')
});

Still building on triggering when the isLoaded property of a record changes, the modified code is just a more clean and simple way of getting the job done.