Jason Jason - 5 months ago 104
AngularJS Question

angular filter with group by date

I am tracking how many times people click a social button in my app. I would like to only give them credit for one click per day. I currently filter the clicks by social platform but I can not figure out how to group by day and only give them a count of 1 per day. below is my current code:

Controller:

Data.get('stats/'+$scope.uid).then(function(data){
$scope.stats = data.data;

// determine if the user has any stats
$scope.hasStats = $scope.stats.length;

$scope.topUsersObjects = $filter('filter')($scope.stats, {
action: "completed"
});
$scope.facebookObjects = $filter('filter')($scope.stats, {
platform: "facebook",
action: "completed"
});
$scope.twitterObjects = $filter('filter')($scope.stats, {
platform: "twitter",
action: "completed"
});
$scope.facebookClickedObjects = $filter('filter')($scope.stats, {
platform: "facebook",
action: "clicked"
});
$scope.twitterClickedObjects = $filter('filter')($scope.stats, {
platform: "twitter",
action: "clicked"
});

$scope.labels = ["Facebook", "Twitter", "Clicked"];

var totalClicked = $scope.facebookClickedObjects.length + $scope.twitterClickedObjects.length;
$scope.data = [$scope.facebookObjects.length, $scope.twitterClickedObjects.length, totalClicked];
});


UPDATE (sample $scope.stats):

Object

action:"clicked ls"
guid:"1200041"
id:"52"
platform:"facebook"
timeclicked:"2015-10-12 21:46:26"
uid:"44043077e53d"


any help is greatly appreciated.

FINAL UPDATED ANSWER:

Thank you @William-b your answer worked however, I ended up doing like this. Please let me know if this is not a good approach. thank you to everyone for the help.

// facebook group by days, completed
$scope.facebookGroupByDay = _.groupBy($scope.facebookObjects, function(item) {
return item.timeclicked.substring(0,10);
});

// get the number of days with a completed post
$scope.fbCount = Object.keys($scope.facebookGroupByDay);

// twitter group by days, clicked
$scope.twitterGroupByDay = _.groupBy($scope.twitterClickedObjects, function(item) {
return item.timeclicked.substring(0,10);
});

// get the number of days with a clicked tweet
$scope.twCount = Object.keys($scope.twitterGroupByDay);

Answer

It sounds like you want to reduce an array of clicks to a count of clicks-by-day.

var days = {}; // let's keep track of days clicked here during the reduction

var clicksByDay = $scope.stats.reduce(function (clickCount, stat) {
  var day = stat.timeclicked.split(' ')[0];
  if (!days[day]) {
    // we didnt count this day yet
    clickCount++;
    days[day] = true; // mark this day as counted
  }
  return clickCount;
}, 0);

if $scope.stats looks like this:

[ 
  { timeclicked: '2015-10-12 12:34:56' },  
  { timeclicked: '2015-10-12 21:46:26'},  
  { timeclicked: '2015-10-13 21:46:26' }  
]

then clicksByDay will be 2 in this case.

P.S. There is nothing stopping you from defining your own angular filter for this type of reduction if it is needed throughout the templates of multiple controllers.

Comments