2

This may be abusing Ember, but I want to create a computed property for the number of items in the store.

I'm trying to prototype a UI that exists entirely client-side. I'm using fixture data with the local storage adapter. That way, I can start off with canned data, but I can also add data and have it persist across reloads.

As I'm currently working on the data layer, I've built a settings route that gives me a UI to reset various models. I would like to add a Handlebars expression like {{modelCount}} so I can see how many records there are in the store. That's quicker than using the Ember Data Chrome extension, which resets to the routes tab on every page reload.

The following will show me the number of records once, but does not change when the number of records changes:

modelCount: function() {
    var self = this;
    this.store.find("my_model").then(function(records) {
        self.set("modelCount", records.get("length"));
    });
}.property()

I get that the store is supposed to proxy an API in the real world, and find returns a promise, but that's about the limit of my knowledge. I don't know how tell Ember to that I want to know how many records there are, or if this is even a valid question.

Ryan
  • 605
  • 7
  • 14

2 Answers2

1

Load the result of store.find into an Ember.ArrayController's content and then bind the length of content to modelCount. An example:

App.SomeRoute = Ember.Route.extend({
  model: function(){
    return this.store.find('my_model');
  }
});

App.SomeController = Ember.ArrayController.extend({
  modelCount: Ember.computed.alias('content.length')
});

See a working example in http://jsbin.com/iCuzIJE/1/edit.

Panagiotis Panagi
  • 9,927
  • 7
  • 55
  • 103
  • Is it possible to do this in an arbitrary variable? I ask because my settings route is acting as a UI to "reboot" a number of models. So what I actually want is something like `{{model1Count}}`, `{{model2Count}}`, ... (I accept that it's also possible I'm trying to do something very un-Emberlike.) – Ryan Jan 18 '14 at 15:49
  • As of Ember 2.x, `ArrayControllers` are [deprecated](https://emberjs.com/deprecations/v1.x/#toc_arraycontroller). Ember's underlying observables require you to implement one of their [Array classes](https://emberjs.com/api/classes/Ember.Array.html) so your templates will update when entries in the array change. –  Mar 28 '17 at 00:26
0

I found a workable solution by combining the answer from @panagiotis, and a similar question, How to load multiple models sequentially in Ember JS route.

In my router, I sequentially load my models:

model: function() {
    var self = this;
    return new Ember.RSVP.Promise(function(resolve, reject) {
        self.store.find("model1").then(function(model1) {
            self.store.find("model2").then(function(model2) {
                self.store.find("model3").then(function(model3) {
                    resolve({
                        model1: model1,
                        model2: model2,
                        model3: model3
                    });
                });
            });
        });
    });
},

Then in my controller, I define simple computed properties:

model1Count: function() {
    return this.get("model1.length");
}.property("model1.length"),

...
Community
  • 1
  • 1
Ryan
  • 605
  • 7
  • 14