1

I am fairly new to Angular and Javascript so am in need of some guidance. I am wanting to work out the sum and average of values within an object array. The objects are pushed into the array through input boxes, here is my code so far:

var myApp = angular.module("myApp", []);

myApp.controller("myController", function($scope){

$scope.newLog = {};

$scope.logs = [
    {project: "", 
     phase: "", 
     date: "", 
     startTime: "", 
     intTime: "", 
     endTime: "", 
     comments: ""}
];

$scope.saveLog = function(){

    //CREATING DELTA TIME
    var newTimeLog = $scope.newLog;
    var begin = (newTimeLog.startTime).getTime();
    var end = (newTimeLog.endTime).getTime();

    var i = newTimeLog.intTime;
    var ii = parseInt(i);
    var intMilisec = ii*60000;

    if( isNaN(begin) )
        {
            return "";
        }

        if (begin < end) {
            var milisecDiff = end - begin;
        }else{
            var milisecDiff = begin - end;
        }

        var minusInt = milisecDiff - intMilisec;

        var milisec = parseInt((minusInt%1000)/100)
            , seconds = parseInt((minusInt/1000)%60)
            , minutes = parseInt((minusInt/(1000*60))%60)
            , hours = parseInt((minusInt/(1000*60*60))%24);

        hours = (hours < 10) ? "0" + hours : hours;
        minutes = (minutes < 10) ? "0" + minutes : minutes;
        seconds = (seconds < 10) ? "0" + seconds : seconds;

        var deltaFormat = hours + " Hours " + minutes + " Minutes";

    newTimeLog["deltaTime"] = deltaFormat;

    $scope.logs.push($scope.newLog);
    $scope.newLog = {};
};

$scope.intSum = function(){
    var sum = 0;
    for (var i = 0; i < $scope.logs.length; i++){
        sum += $scope.logs[i].intTime;
    }
    return sum;
};

});

So the intSum function is where I am having issues - I am wanting to sum the intTime properties for all the objects. So if object1's intTime = 1, object2's intTime = 2, object3's intTime = 3 the intSum should be 6. However what I am getting from the IntSum currently is 123.

Any help would be greatly appreciated!

AT82
  • 71,416
  • 24
  • 140
  • 167
Bex
  • 71
  • 5

4 Answers4

2

Try:

sum += parseInt($scope.logs[i].intTime);

Instead of:

sum += $scope.logs[i].intTime;

EDIT: I would recommend you have a look at reduce function, which is the javascript way of looping on your array in this case: https://www.w3schools.com/jsref/jsref_reduce.asp


EDIT2: You initialize $scope.logs.intTime to "". This first value stays in your array and generates NaN. I suggest you initialize your array like this:

$scope.logs = [];
RaphaMex
  • 2,781
  • 1
  • 14
  • 30
  • This is helpful thank you. However it is still getting stuck, for some reason everytime I click the save button which toggles saveLog() it sets the sum variable in intSum() to NaN? – Bex Jun 08 '17 at 18:51
  • To help you more, I need your amended js file and also your html to reproduce your issue. – RaphaMex Jun 08 '17 at 22:29
0

The intTime is defined in your object as String. So when you are doing the sum, it is actually doing a string concatenation. Convert to Number using pasrseInt and do the sum.

Abhi81
  • 1
  • 1
0

Try using parseInt when you sum+=:

$scope.intSum = function(){
    var sum = 0;
    for (var i = 0; i < $scope.logs.length; i++){
        sum += parseInt($scope.logs[i].intTime);
    }
    return sum;
};
AKMorris
  • 422
  • 4
  • 16
0
  1. You need to convert intTime of type string to int
  2. You can use JavaScript reduce() function

    • arr.reduce(callback, [initialValue])
    • callback = function(accumulator, currentValue) { return accumulator + currentValue } //accumulator is the currentSum since the last callback
  3. Example: http://jsfiddle.net/GruffBunny/4cFU3/

    • Your sum function can be written as:

       $scope.sum = function(items, prop){ //items is the array, prop is the property you want to its value to be calculated 
           return items.reduce( function(a, b){
               return a + parseInt(b[prop]);  //in the first attempt, a=0 which is the same as initialValue
           }, 0);  //initially sum=0, so initialValue is 0
        };
      
    • In your case, I would make the function call as $scope.sum($scope.logs, 'iniTime')
  4. References:

grepLines
  • 2,478
  • 3
  • 21
  • 32