Reputation: 267
I'm working on learning Angular JS by creating my own app. My focus is Angular, so I'm not connecting to a database like one would in the real world - thus I have an array of movies = [{title: '', genre: '', rating: ''}...]
hard coded into my js file.
I have a series of buttons with the different movie ratings: G, PG, PG13, R. Each button should work as a filter and then return movies who's rating matches the button. When the button is clicked, Data.selectedRating
stores the value. However, I'm running into trouble with the built-in filter because if there are no movies with the desired rating, it will return all of them when it should return none. And if the "PG" button is clicked it returns movies with the rating of PG and PG13.
Is there a way to fix this? I thought I may need to make a custom filter, but I'm not really sure how to go about it (as I'm sure you'll be able to tell). Any suggestions? Thanks!
Here's what I have:
HTML
// Data.selectedRating holds the value of the button that was clicked
// Built in filter looked like this:
// ng-repeat="movie in movies | filter: Data.selectedRating"
<table>
<tr ng-repeat="movie in movies">
<td>
{{movie.title | filterRating}}
</td>
</tr>
</table>
JS
angular.module('movieApp', ['ngAnimate', 'ui.router'])
.factory('Data', function() {
return { sortType: '',
selectedGenre: '',
selectedRating: ''};
})
.controller('formController', ['$scope', 'Data', function($scope, Data) {
$scope.Data = Data;
$scope.movies = [
{title:'Pitch Perfect 2', genre: 'Musical', rating: 'PG13'},
{title:'Longest Ride', genre: 'Romance', rating: 'PG13'},
{title:'Furious 7', genre: 'Action', rating: 'PG13'},
{title:'Home', genre: 'Adventure', rating: 'PG'},
{title:'Insurgent', genre: 'Action', rating: 'PG13'}
];
}])
.filter('filterRating', function() {
var out = [];
return function(selectedRating, a) {
if(selectedRating.rating == Data.selectedRating)
{
out.push(selectedRating.title);
}
}
return out;
});
============================================
Update - I have added the suggestions by a few of the comments below - Thanks! Now, instead of the name of the movie, "undefined" is return. Any ideas?
Updated Code: HTML:
...
<td>
{{movie.title | filterRating}}
</td>
...
JS
.filter('filterRating', function() {
return function(selectedRating, movies) {
var out = [];
if(Data.selectedRating == selectedRating.rating)
{
alert(' in here');
out.push(movies.title);
}
return out;
}
});
Upvotes: 1
Views: 80
Reputation: 4147
You filter function should be like this
.filter('filterRating', function() {
return function(movies) {
var out = [];
angular.forEach(movies, function(movie) {
if (movie.rating == Data.selectedRating) out.push(movie);
});
return out;
}
});
Upvotes: 2
Reputation: 1711
Your code should be :
HTML
<tr ng-repeat="movie in movies | filterRating ">
<td>
{{movie.title }}
</td>
</tr>
JS
.filter('filterRating', function(Data) {
return function(selectedRating) {
var out = [];
for (var i = 0; i < selectedRating.length; i++) {
if(selectedRating[i].rating == Data.selectedRating)
{
out.push(selectedRating[i]);
}
}
return out;
}
});
The reason for it, is that you want to filter the movie object and not the title itself
PLUNKR : http://plnkr.co/edit/nYAX9kiBhqYyXCqaMYhc?p=preview
Upvotes: 1