0

I'm learning through angularjs (not 2) and am trying to figure out how to calculate a customer order total.

my data looks like this:

var customers = [
            {
                id: 1, 
                joined: '2000-12-02', 
                name:'John', 
                city:'Chandler', 
                orders: [
                    {
                        id: 1,
                        product: 'Shoes',
                        total: 9.9956
                    }
                ]
            }, 
            {
                id: 2, 
                joined: '1965-01-25',
                name:'Zed', 
                city:'Las Vegas', 
                orders: [
                    {
                        id: 2,
                        product: 'Baseball',
                        total: 9.995
                    },
                    {
                        id: 3,
                        product: 'Bat',
                        total: 9.995
                    }
                ]
            }
]

I have a factory and a controller that receives that data and...

my controller looks like:

(function() {

    var CustomersController = function ($scope, $log, customerFactory) {
        $scope.sortBy = 'name';
        $scope.reverse = false;
        $scope.customers = [];

        function init () {

            customerFactory.getCustomers()
                .success(function(customers) {
                    $scope.customers = customers;

            })
            .error(function(data, status, headers, config){
                $log.log(data.error + ' ' + status );

            });

        }

        init();

        $scope.doSort = function(propName) {
           $scope.sortBy = propName;
           $scope.reverse = !$scope.reverse;
        };


    };

    CustomersController.$inject = ['$scope','$log' ,'customerFactory'];

    angular.module('customersApp')
      .controller('CustomersController', CustomersController);

}());

my view looks like this:

<h2>Customers</h2>
Filter: <input type="text" ng-model="customerFilter.name" />
<br /><br />
<table>
    <tr>
        <th ng-click="doSort(name)">Name</th>
        <th ng-click="doSort(city)">City</th>
        <th ng-click="doSort(joined)">Joined</th>
        <th>&nbsp;</th>
    </tr>
    <tr ng-repeat="cust in customers | filter:customerFilter | orderBy:sortBy:reverse">
        <td>{{ cust.name }}</td>
        <td>{{ cust.city }}</td>
        <td><a href="#/orders/{{ cust.employeeid }}">View Orders</a></td>
    </tr>
</table>
<br />
<span>Total customers: {{ customers.length }} </span>

I understand how I would add in an order total column...but how do you calculate it given the json that comes back?

---------------EDIT--------------

I think this is headed in the right path?

    customerFactory.getCustomers()
        .success(function(customers) {
            for(var i = 0; i < customers.length; i++) {
                var currCustomer = customers[i];
                var aCustomerTotal = 0;

                if (currCustomer.hrs) {

                    for (var j = 0; j < currCustomer.hrs.length; j++) {
                        aCustomerTotal += parseInt(currCustomer.hrs[j].bllhrs);
                    }
                } else {
                    aCustomerTotal=0
                }
                customers[i].orderTotal = aCustomerTotal;
                console.log(currCustomer.lastname + " total: " + aCustomerTotal);
            }
            // after the exeuction of this logic set your $scope's customer to the modified object.
            $scope.customers = customers;
        })
4
  • you have to iterate data and calculate in controller Commented Oct 12, 2016 at 19:05
  • also you have to pass property name ng-click="doSort('name')" follow the same for other ng-click's Commented Oct 12, 2016 at 19:05
  • @charlietfl I think I get that...would that create a new element in customers too then? Would I have an customers.orderTotal to then? Commented Oct 12, 2016 at 19:07
  • that would probably be best. Then it only needs to be calculated once when you get the data. Unless you are editing these and need live calcs Commented Oct 12, 2016 at 19:10

2 Answers 2

1

If all you are stuck on is getting a total per customer -> you can use a simple double for loop:

.success(function(customers) {
    for(var i = 0; i < customers.length; i++) {
        var currCustomer = customers[i];
        var aCustomerTotal = 0;
        for (var j = 0; j < currCustomer.orders.length; j++) {
            aCustomerTotal += currCustomer.orders[j].total;
        }
        customers[i].orderTotal = aCustomerTotal;
        console.log(currCustomer.name + " total: " + aCustomerTotal);
    }
    // after the exeuction of this logic set your $scope's customer to the modified object.
    $scope.customers = customers;
}
Sign up to request clarification or add additional context in comments.

5 Comments

I see where you're going with this...do I put this in the controller? and if so...how do you append that to $scope.customers = customers;?
I made an edit with what you suggested...but I don't understand how to append the result back to the initial json object...sorry...new to this whole thing...
Edited my answer to show how to modify the customer object with the customer's total and then add that modified object to the scope.
I edited my answer with what you had but I'm getting an cannot read property 'length' of undefined now at the hrs.length. Tried to put in an if statement but can't get it to work still...I get 3 results to show in the console but then get the undefined error.
That means some of your customer objects do not have an hrs propety. Check to make sure each one has that property.
1

You can create custom filter for that (let's say you also use lodash for simplification):

angular.module('customersApp', [])
.filter('customerTotal', function() {
  return function(customer) {
    return _.reduce(customer.hrs, function(sum, hrs) {
      return sum + parseInt(hrs.bllhrs);
    }, 0);
  };
});

And you can use that filter like that:

<td>{{ curr.name }} total: {{ cust | customerTotal }}</td>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.