Calculate and add JSON with new AngularJS key and value

So I have this JSON data group and I want to do some calculations and add the results and create a new key in JSON. I have set up the calculation services which I then use in the controller. But the problem is that it only pushes the last known value into each newly generated "rate" key.

JSON looks like this:

[{  "date"      : "2015-09-01",
"start"     : "2015-09-01 08:00:00",
"finish"    : "2015-09-01 10:00:00",
"loggedIn"  : "2015-09-01 08:06:27",
"loggedOut" : "2015-09-01 10:06:27"

}, { "date"      : "2015-09-02",
 "start"     : "2015-09-02 08:00:00",
 "finish"    : "2015-09-02 10:00:00",
 "loggedIn"  : "2015-09-02 08:02:05",
 "loggedOut" : "2015-09-02 10:02:11"

}, { "date"      : "2015-09-03",
 "start"     : "2015-09-03 13:00:00",
 "finish"    : "2015-09-03 14:30:00",
 "loggedIn"  : "2015-09-03 13:11:05",
 "loggedOut" : "2015-09-03 14:31:01"

}, { "date"      : "2015-09-04",
 "start"     : "2015-09-04 13:00:00",
 "finish"    : "2015-09-04 14:30:00",
 "loggedIn"  : "2015-09-04 13:01:05",
 "loggedOut" : "2015-09-04 14:31:01"

}, { "date"      : "2015-09-05",
 "start"     : "2015-09-05 18:00:00",
 "finish"    : "2015-09-05 21:00:00",
 "loggedIn"  : "2015-09-05 18:30:05",
 "loggedOut" : "2015-09-05 21:00:51"

}]

      

The service looks like this:

angular.module('appService', [])
.service('CalculationService', function(){
    this.getTheRate = function(start, end, login) {
        if ( typeof (start) && typeof (end) && typeof (login) === 'undefined') {
            return 'n/a';
        } else {
            var startTime =  new Date(start).getTime() / 60000,
                endTime   =  new Date(end).getTime()   / 60000,
                loginTime =  new Date(login).getTime() / 60000;

            var totalTime  = endTime - startTime,
                lateness   = loginTime - startTime,
                percentile = 100 - (lateness / totalTime) * 100;

            return parseFloat(percentile).toFixed(1);
        }
    };

      

The controller looks like this:

angular.module('MainController', [])
 .controller('mainCtrl', [
    '$http', 
    'CalculationService', 
    function($http, CalculationService){

         var logins = this;

         logins.dataStore = [];

         logins.add = function(temp){
             logins.dataStore.push(temp);
         };

         $http.get('./theData.json').success(function(data){
            logins.data = [];
            logins.data = data;
         });

         logins.getRate = function(start, end, login) {
            angular.forEach(logins.data, function(obj){
                obj.rate = {};
                obj.rate = CalculationService.getTheRate(start, end, login);
                return obj.rate;
            });
         };
}]);

      

The markup looks like this:

<div ng-controller="mainCtrl as main">
<section class="view-section">
            <div class="view" ng-repeat="item in main.data"> 
                {{ main.getRate(item.start, item.finish, item.loggedIn) }}
                {{ item.rate }}
            </div>
</section>
</div>

      

{{item.rate}} is only output in ngRepeat, but when I checked the data through {{main.data}} a key is generated for each instance, but the value is however not inserted correctly, with all "rate" keys assigned to each the same last known calculated value, rather than separate calculated values โ€‹โ€‹for each instance. Any ideas?

+3


source to share


1 answer


The function getRate

calls the calculation in a loop over all data (using angular.forEach

), but using the same values start

, finish

and login

. Then you call this function internally ngRepeat

, which creates the second loop. Therefore, each iteration of the loop ngRepeat

assigns the speed of the current element to all elements. This is why by the time you are done, all items have the speed of the last item.

Instead, call the speed computation loop in the controller as soon as the data is received (literally right after the assignment logins.data

in the callback $http.get

), not in the {{...}} expression. As noted in the comments, it is not a good idea to reference a function with side effects inside an expression.



Also note that this error is made possible because your function getRate

assigns speed to an object (in fact, all objects) and returns it. This is confusing and error prone. It would be easier if the function would either assign a speed or return it, but not both.

+1


source







All Articles