Reputation: 1568
I have two models
Time Entry
TimeTray.TimeEntry = DS.Model.extend({
startTime: DS.attr('date'),
endTime: DS.attr('date'),
status: DS.attr('string'),
offset: DS.attr('number'),
isDeleted: DS.attr('boolean'),
task: DS.belongsTo('task'),
duration: function () {
return TimeTray.timeController.duration(this.get('startTime'), this.get('endTime'));
}.property('startTime', 'endTime'),
title: function () {
if (this.get('task')) {
return this.get('task').get('title');
}
}.property('task')
});
Task
TimeTray.Task = DS.Model.extend({
title: DS.attr('string'),
totalTime: function () {
var timeEntries = this.get('timeEntries')
for (var entry in timeEntries) {
var duration = entry.get('duration')
}
}.property('timeEntries'),
isDeleted: DS.attr('boolean'),
isRecording: DS.attr('boolean', { defaultValue: false }),
timeEntries: DS.hasMany('TimeEntry')
});
how do i get an array of timeentry entities so that i can calculate the total time spent on a task? the above method doesnt work.
the Time Entry title property works.
Upvotes: 0
Views: 89
Reputation: 19128
You have some errors in your code:
1- In that foreach
...
for (var entry in timeEntries) {
var duration = entry.get('duration')
}
...
The for ... in
not work like you expected for arrays, you need to use or for(var i; i < array.length; i++)
or the array.forEach(func)
.
2 - In the computed property totalTime
you will use the duration
property of the TimeEntry
, you need to specify that dependency using property('[email protected]')
.
3 - Probally your timeEntries
property will be fetched from the server, so you will need to use the async: true
option, in your definition:
timeEntries: DS.hasMany('TimeEntry', { async: true })
4 - If your timeEntries
is always empty, even the data being saved in your database. Make sure that your returned json have the timeEntries ids. For example:
{id: 1, title: 'Task 1', timeEntries: [1,2,3] }
The changed code is the following:
TimeTray.Task = DS.Model.extend({
title: DS.attr('string'),
totalTime: function () {
var duration = 0;
this.get('timeEntries').forEach(function(entry) {
duration += entry.get('duration')
});
return duration;
}.property('[email protected]'),
isDeleted: DS.attr('boolean'),
isRecording: DS.attr('boolean', { defaultValue: false }),
timeEntries: DS.hasMany('TimeEntry', { async: true })
});
And this is the fiddle with this sample working http://jsfiddle.net/marciojunior/9DucM/
I hope it helps
Upvotes: 1
Reputation: 6709
Your totalTime
method is neither summing timeEntry durations nor returning a value. Also your property
is not set up correctly (use @each
). The correct way of doing this is:
totalTime: function () {
var timeEntries = this.get('timeEntries')
var duration = 0;
for (var entry in timeEntries) {
duration = duration + entry.get('duration');
}
return duration;
}.property('[email protected]'),
Or, more elegantly using getEach()
and reduce()
:
totalTime: function () {
return this.get('timeEntries').getEach('duration').reduce(function(accum, item) {
return accum + item;
}, 0);
}.property('[email protected]'),
Upvotes: 0