Arter
Arter

Reputation: 2324

Get filtered value from view to controller

I use ng-repeat to show my array of objects. One of the attributes is video duration, and I used filter to directly show sum of all meta_durations. here is filter

app.filter('sumProduct', function() {
 return function (input) {
  var i = input instanceof Array ? input.length : 0;
  var a = arguments.length;
  if (a === 1 || i === 0)
      return i;

  var keys = [];
  while (a-- > 1) {
      var key = arguments[a].split('.');
      var property = getNestedPropertyByKey(input[0], key);
      if (isNaN(property))
          throw 'filter sumProduct can count only numeric values';
      keys.push(key);
  }

  var total = 0;
  while (i--) {
      var product = 1;
      for (var k = 0; k < keys.length; k++)
          product *= getNestedPropertyByKey(input[i], keys[k]);
      total += product;
  }
  return total;

  function getNestedPropertyByKey(data, key) {
    for (var j = 0; j < key.length; j++)
        // data = dataDuration[key[j]];
        data = data.meta_duration;;
    return data;
}
}
})

and in view

<table>
    <thead>
    <tr>
        <th>Media name</th>
        <th>Media type</th>
        <th>Media duration in sec</th>
        <th>Media thumbnail</th>
    </tr>
</thead>
<tbody>
    <tr ng-repeat="media in myMediaItems">

        <td>{{media.name}}</td>
        <td>{{media.type}}</td>
        <td>>{{media.meta_duration}}</td>
        <td><img src="{{media.thumbnail}}" alt="" /></td>
    </tr>

</tbody>
<tr>
    <td></td>
    <td></td>
    <td>Total duration {{ myMediaItems|sumProduct:'duration' }}</td> //here is where i use custom filter
    <td></td>

</tr>
</table>

How to get total duration value in the controller? Dynamically i add (push) media to list from another list with all media.

 $scope.addToMediaList = function(item) {
          var seconds = parseInt(item.meta_duration);
          $scope.view_duration = Math.floor(moment.duration(seconds,'seconds').asHours()) + ':' + moment.duration(seconds,'seconds').minutes() + ':' + moment.duration(seconds,'seconds').seconds();($scope.view_duration_seconds, "HH:mm:ss");
          $scope.myMediaItems.push(item);
          $scope.sumDuration = $filter("sumProduct")(myMediaItems.meta_duration); //i try like this, set on $scope.sumDuration but in conole i get only number 0
          $scope.myMediaItemsId.push(item.id);
          $scope.input = "";
        };

Thanks

Upvotes: 0

Views: 53

Answers (3)

Arter
Arter

Reputation: 2324

I solved this by forwarding the returned value from the custom filter to controller.

var filtered = $filter('sumProduct')($scope.myMediaItems); 
          console.log(filtered)

Filtered value is sum. thnx @ Amaya San

Upvotes: 0

John Velasquez
John Velasquez

Reputation: 3451

I simplified your filter.

try this

app.filter('sumProduct', function() {
   return function (input) {
     var i = input instanceof Array ? input.length : 0;
     var a = arguments.length;
     if (i === 0)
       return i;
     var total = 0;
     for(var x of input){
       var duration = parseFloat(x.meta_duration);
       if(isNaN(duration)){
           throw 'filter sumProduct can count only numeric values';
       }
       total += duration;
    }
    return total;
  }
});

Upvotes: 1

nikhil garg
nikhil garg

Reputation: 21

You can use something like this

<div ng-init="sumDuration = myMediaItems|sumProduct:'duration'"> </div>

Upvotes: 0

Related Questions