angularjscoffeescriptsteroids

Can't sum values in Angularjs if one value is an empty string


I am building a simple Appgyver mobile app using Angularjs and Coffeescript - I'm a beginner with both of these.

I wish to determine the total cost for a list of up to 20 items stored on the database. However, there may be less than 20 items.

I have attempted to do the calculation with ng-bind, which works perfectly as long as all strings contain values. However, if there are less than 20 pairs (values go up to q20 and p20) then the calculation returns NaN.

I would like to determine the total of all existing values for the list. I have looked at numerous examples on stackoverflow, Angularjs.org and other sites and have experimented with a myriad of alternative methods, however I think I lack the basic understanding of how to make this work. Any help would be appreciated.

This is the code I have used, shortened to 3 pairs instead of 20:

 <span ng-bind="client['q1'].price * client['p1'].price + client['q2'].price 
* client['p2'].price + client['q3'].price * client['p3'].price"></span>

This is the existing controller:

angular
  .module('client')
  .controller("ShowController", ($scope, Client, supersonic) ->
$scope.client = 0;
$scope.showSpinner = true
$scope.dataId = undefined


_refreshViewData = ->
  Client.find($scope.dataId).then (client) ->
    $scope.$apply ->
      $scope.client = client
      $scope.showSpinner = false


supersonic.ui.views.current.whenVisible ->
  _refreshViewData() if $scope.dataId

supersonic.ui.views.current.params.onValue (values) ->
  $scope.dataId = values.id
  _refreshViewData()

$scope.remove = (id) ->
  $scope.showSpinner = true
  $scope.client.delete().then ->
    supersonic.ui.layers.pop()
  )

Solution

  • I think you are overloading (in the linguistic sense, not the coding sense) ng-bind. Doing all of that code in your HTML is messy and is not what it was created for. You would be better off doing the math in your controller, and then referencing it in ng-bind. You have only 3 pairs here, but you say you have 20, and could be more, so do it that way:

    <span ng-bind="totalPrice"></span>
    

    And in your controller:

      var setTotalPrice = function() {
        var ret = 0, i, maxClient = 6, client = $scope.client; // or however else you keep track of them
        for (i=1;i<=maxClient;i++) {
          if (client['q'+i] && client['q'+i].price && !isNaN(client['q'+i].price) &&
              client['p'+i] && client['p'+i].price && !isNaN(client['p'+i].price)) {
             ret += (client['q'+i].price * client['p'+i].price);
         }
      }
      $scope.totalPrice = ret;
    };
    $scope.setTotalPrice = setTotalPrice;
    setTotalPrice();
    

    Just call setTotalPrice in your controller whenever you want, or on an ng-click.