1
votes

I am working on an Ember.js app (Ember 1.7, Ember Data Beta 9, REST Adapter).

I have the following models:

App.Task = DS.Model.extend({
    tasktimes: DS.hasMany('tasktime', {async: true}),
    // ...
});

App.Tasktime = DS.Model.extend({
    task: DS.belongsTo('task', {async: true}),
    user: DS.belongsTo('user', {async: true}),
    duration: DS.attr()
  //...
});

What I want to achieve is to get an array of all tasktimes per user with the total duration.

For example:

Task 1:

  • Tasktime 1: User = 1 / Duration = 5
  • Tasktime 2: User = 1 / Duration = 2
  • Tasktime 3: User = 2 / Duration = 4

Should have the following result:

[
    {user: user1, totalDuration: 7},
    {user: user2, totalDuration: 4}
]

I do not know how to achieve such a nested computed property. I tried various ways, but none has worked so far. (In my early approaches, the user was always unresolved and therefore the whole thing did not work).

The problem is that I need two levels of "then" inside of two foreach loops and I do not know how to get this to work with promises.

This would be the basic idea:

durationPerUser: function() {
    var data = Ember.A();

    var tt = this.get("tasktimes");
    tt.forEach(function(item) {
      item.get("user").get(function(user) {
        // If no entry exists yet, create a new one
        if(data[item.get("user.id")] == undefined) {
          data[item.get("user.id")] = {totalDuration: 0, user: item.get("user")};
        }

        // Add the hours to the array
        data[item.get("user.id")].totalDuration += item.get("duration");
      });
    });

    return data;
  }.observes("[email protected]", "[email protected]", "[email protected]", "tasktimes.@each"),

which of course doesn't work because of the involved promises. I'm really not an expert with promises etc., so maybe there is some way to do this which I am simply missing so far.

1
I know it's been awhile, but did you ever figure this out? I have an almost identical scenario involving a contentItem and its related tags, where I want to operate on all the tags for a given contentItem.Joe

1 Answers

0
votes

Wouldn't something like that work?

App.Task = DS.Model.extend({
    tasktimes: DS.hasMany('tasktime', {async: true}),
    // ...

    durationPerUser: function(){
      var users = this.get('users');
      var tasktimes = this.get('tasktimes');
      var result = [];
      users.forEach(function(user){
        var thisUsersTasktimes = tasktimes.filterBy({'user', user })
        var totalDuration = 0;
        thisUsersTasktimes.forEach(function(tasktime){
          totalDuration += tasktime.get('duration');
        });
        result.push({user: user, totalDuration: totalDuration});
      });
      return result;
    }.property('users.@each', 'tasktimes.@each')
})

on second thought that would require an association between users and tasks, which I just realised you do not have at the moment, but you can easily make a has many through association and serve a user ids array with your tasks.