absingharora
absingharora

Reputation: 134

Incorrect sum of rows in HTML table using Angular

I am stuck with getting the correct total revenue (total Media Cost, total Revenue, and total Profit) for each month. I have created a plunker for the same. Can you, please, help?

Plunker http://plnkr.co/edit/7taIugnhGPZbqCMGpUza?p=preview

script.js

var app = angular.module('plunker', []);
app.controller('AppController',['$scope',
  function($scope) {
    $scope.total = function(i){
      var totalMediaCost = 0;
      var totalRevenue = 0;
      var totalProfit = 0;
      $scope.array = [];
        console.log('i.revenue', i.revenue);
        for (var data in i.revenue){
          console.log('data', data);
          totalMediaCost += i.revenue[data].a;
          totalRevenue += i.revenue[data].b;
          totalProfit += i.revenue[data].c;

        } 
      $scope.array.push({'totalMediaCost': totalMediaCost});

    }

    $scope.rows = [
    {
      "month": "Feb-01",
      "revenue": [
        {
          "account": {
          "id": 1,
          "name": "user alpha"
        },
          "a": 111,
          "b": 222,
          "c": 333
        },
        {
          "account": {
          "id": 2,
          "name": "user beta"
        },
          "a": 1,
          "b": 2,
          "c": 3,
        },
        {
          "account": {
          "id": 3,
          "name": "user gamma"
        },
          "a": 141,
          "b": 242,
          "c": 343
        }
      ]
     },
     {
      "month": "Mar-02",
      "revenue": [
      {
        "account": {
        "id": 1,
        "name": "user alpha"
      },
        "a": 100,
        "b": 200,
        "c": 300
      },
      {
        "account": {
        "id": 14,
        "name": "user beta"
      },
        "a": 101,
        "b": 202,
        "c": 303
      },
      {
        "account": {
        "id": 3,
        "name": "user gamma"
      },
        "a": 241,
        "b": 342,
        "c": 443
      }
     ]
    }
  ];

  }
]
);

index.html

<!doctype html>
<html ng-app="plunker">

<head>
  <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
  <script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.0/js/bootstrap.min.js"></script>
  <script src="script.js"></script>
  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
  <link rel="stylesheet" href="style.css" />
</head>

<body ng-controller="AppController">

  {{rows | json}}

  <hr>

  <table class="table">

    <tr>
      <th></th>
      <th>Account</th>
      <th>Media Cost</th>
      <th>Revenue</th>
      <th>Profit</th>
    </tr>
    <tbody ng:repeat="i in rows">
      <tr>
        <td rowspan="{{i.revenue.length+1}}">{{i.month}}</td>
        <tr ng:repeat="data in i.revenue">
          <td>{{data.account.name}}</td>
          <td>{{data.a}}</td>
          <td>{{data.b}}</td>
          <td>{{data.c}}</td>
        </tr>
        <tr ng-init="total(i)">
          <td></td>
          <td>Total Revenue</td>
          <td>{{array[0].totalMediaCost}}</td>
          <td>{{}}</td>
          <td>{{}}</td>
        </tr>
      </tr>
    </tbody>

  </table>

</body>
</html>

Upvotes: 2

Views: 71

Answers (3)

Fidel90
Fidel90

Reputation: 1838

I've edited your approach a little. Check out this plunker.

JS:

$scope.total = {
    cost : [],
    revenue : [],
    profit : []
  };

  for (var month in $scope.rows) {
    if ($scope.rows.hasOwnProperty(month)) {
      var revData = $scope.rows[month]["revenue"],
          totalCost = 0,
          totalRevenue = 0,
          totalProfit = 0;

      revData.forEach(function (account) {
        totalCost += account["a"];
        totalRevenue += account["b"];
        totalProfit += account["c"];
      });

      $scope.total.cost.push(totalCost);
      $scope.total.revenue.push(totalRevenue);
      $scope.total.profit.push(totalProfit);
    }
  }

HTML:

<tbody ng:repeat="i in rows">
     <tr>
      <td rowspan="{{i.revenue.length+1}}">{{i.month}}</td>
      <tr ng:repeat="data in i.revenue">
        <td>{{data.account.name}}</td>
        <td>{{data.a}}</td>
        <td>{{data.b}}</td>
        <td>{{data.c}}</td>
      </tr>
      <tr>
        <td></td>
        <td>Total</td>
        <td>{{total.cost[$index]}}</td>
        <td>{{total.revenue[$index]}}</td>
        <td>{{total.profit[$index]}}</td>
      </tr>
  </tr>
  </tbody>

Upvotes: 1

Nikhilesh K V
Nikhilesh K V

Reputation: 1480

Here is a working sample : http://plnkr.co/edit/bB7up1rhOSad9Xoq3SsQ?p=preview


Its better to use the existing rows array and push the total inside each row object rather than creating a separate variable in scope.


$scope.total = function(i,index) {
    $scope.rows[index].totalMediaCost = totalMediaCost;
}

<tr ng-init="total(i,$index)">

Upvotes: 3

Thorarins
Thorarins

Reputation: 1904

you are using the same variable twice, wich gives you the totalMediaCost of the last array for both tables

you should change the totalMediaCost to an array or similar

Upvotes: 1

Related Questions