Reputation: 57
I want to filter filtered results.
I have the following JSON
$scope.JSON = [
{
"Animal": "Horse",
"Status": "awake",
"LastUpdate": {
"$date": 1473248184519
}
},
{
"Animal": "Rabbit",
"Status": "awake",
"LastUpdate": {
"$date": 1473248194240
}
},
{
"Animal": "Rabbit",
"Status": "eating",
"LastUpdate": {
"$date": 1473249639255
}
},
{
"Animal": "Horse",
"Status": "eating",
"LastUpdate": {
"$date": 1473249652549
}
},
{
"Animal": "Horse",
"Status": "sleeping",
"LastUpdate": {
"$date": 1473249656338
}
}
]
and the following filter function
$scope.filtering = filtering;
function filtering(animals){
var temp = [].concat(animals)
var animalsExisting = []; // To keep track of animals already added
return temp.reverse().filter(function(animal){
var notAdded = animalsExisting.indexOf(animal.Animal) === -1;
if(notAdded) {
animalsExisting.push(animal.Animal);
}
return notAdded;
})
}
See also this plunkr: https://plnkr.co/edit/OQVjB47bpS9fKubO2lum?p=preview
How do I filter the returned Array notAdded with the Status, e.g. I want to show only the last & "eating" animals => result: Rabbit?
Upvotes: 0
Views: 45
Reputation: 1420
Easiest way - using native Angular filter
<tr ng-repeat="roll in filtering(JSON) | filter : { Status: 'eating' }">
Because either Angular will invoke filtering(JSON)
on each $digest
(which occures pretty often) it would be much better if you render a static list, not the return result of the function.
What I suggest is you rewrite your code to something along the lines
$scope.filters = {
status: null
};
$scope.filteredAnimals = [];
$scope.getLastStatusesForEachAnimal = function() {
var map = {};
return [].concat($scope.JSON)
.reverse()
.filter(function(animal) {
return !map[animal.Animal] ? (map[animal.Animal] = true) : false;
});
};
$scope.filterAnimals = function() {
$scope.filteredAnimals = $scope.getLastStatusesForEachAnimal()
.filter(function(animal) {
return $scope.filters.status ? animal.Status === $scope.filters.status : true;
});
};
$scope.filterAnimals();
Write your own filter with caching, example
.filter('animalStatusFilter', function() {
var cache = {
params: {},
result: null
};
return function(animals, status, onlyLast) {
var params = {
animals: animals,
status: status,
onlyLast: onlyLast
};
if (validateCache(params)) {
return cache.result;
}
animals = onlyLast ? getLastStatusesForEachAnimal(animals) : animals;
if (status) {
animals = animals.filter(function(animal) {
return status ? animal.Status === status : true;
});
}
cache.params = params;
cache.result = animals;
return animals;
};
function validateCache(params) {
return params.animals === cache.params.animals &&
params.status === cache.params.status &&
params.onlyLast === cache.params.onlyLast
}
function getLastStatusesForEachAnimal(animals) {
var map = {};
return [].concat(animals)
.reverse()
.filter(function(animal) {
return !map[animal.Animal] ? (map[animal.Animal] = true) : false;
});
}
})
Upvotes: 1