Ember.js: Calculate the sum of a property of all child models

ember.js, model

Solution

The following should do it. There might be an more concise solution using reduce, but i have never used it myself :-)

App.List = DS.Model.extend({
    name: DS.attr('string'),
    users: DS.hasMany('App.User'),
    tweetsUnread: function(){
        var users = this.get("users");
        var ret = 0;
        users.forEach(function(user){
            ret += users.get("tweetsUnread");
        });
        return ret;
    }.property("users.@each.tweetsUnread")
});

Update: This is a more elegant solution using reduce. I have never used it and this isn't tested but i am quite confident that this should work:

App.List = DS.Model.extend({
    name: DS.attr('string'),
    users: DS.hasMany('App.User'),
    tweetsUnread: function(){
        var users = this.get("users");
        return users.reduce(0, function(previousValue, user){
            return previousValue + users.get("tweetsUnread");
        });
    }.property("users.@each.tweetsUnread")
});

In Ember 1.1 the API for reduce has changed! Thx @joelcox for the hint, that the parameters initialValue and callback have changed their position. So here the correct version of the code:

App.List = DS.Model.extend({
    name: DS.attr('string'),
    users: DS.hasMany('App.User'),
    tweetsUnread: function(){
        var users = this.get("users");
        return users.reduce(function(previousValue, user){
            return previousValue + user.get("tweetsUnread");
        }, 0);
    }.property("users.@each.tweetsUnread")
});

Problem

My application has the following models: ``` App.Store = DS.Store.extend({ revision: 11, adapter: 'DS.FixtureAdapter' }); App.List = DS.Model.extend({ name: DS.attr('string'), users: DS.hasMany('App.User'), tweetsUnread: function(){ ///////////////////////////////////////// // Code to dynamically calculate the sum // of tweetsUnread property of all // App.User that are related to this list ///////////////////////////////////////// } }); App.User = DS.Model.extend({ screenName: DS.attr('string'), tweets: DS.hasMany('App.Tweet'), tweetsUnread: function(){ // TODO: check if this is the correct way to do it return this.get('tweets').get('length'); }.property('tweets.@each'), list: DS.belongsTo('App.List') }); App.Tweet = DS.Model.extend({ text: DS.attr('string'), user: DS.belongsTo('App.User') }); ``` How can I calculate the sum of all App.User.tweetsUnread and make it automatically update App.List.tweetsUnread?

Original source