Reputation: 171
I want to filter the games by genre. pdList is the array of objects(games).To do this i'm using Array.filter(). but its not working. below is the code. Correct me if my approach is wrong. its not giving any error also in the console.
Vuejs code:
new Vue({
el: "#app",
data: {
currentFilter:"all",
pdList:[,
{
"title": "Double Dragon: Neon",
"url": "/games/double-dragon-neon/xbox-360-131320",
"platform": "Xbox 360",
"score": 3,
"genre": "Fighting",
"editors_choice": "N",
"release_year": 2012
},
{
"title": "Guild Wars 2",
"url": "/games/guild-wars-2/pc-896298",
"platform": "PC",
"score": 9,
"genre": "RPG",
"editors_choice": "Y",
"release_year": 2012
}]
},
methods: {
filterByGenre:function(filterby){
this.currentFilter = filterby;
},
filteredGames:function(pdList){
console.log("inside filtergames");
if(this.currentFilter == "all"){
return pdList;
}else{
return pdList.filter(function(game){
console.log(this.currentFilter);
return game.genre == this.currentFilter;
});
}
}
}
})
HTML
<div id="app">
<h2>Game Lister:</h2>
<ol>
<li v-for="game in filteredGames(pdList)">
{{game.genre}}
</li>
</ol>
</div>
<select v-model="currentFilter">
<option value="all">all</option>
<option value="Platformer">Platformer</option>
<option value="Platformer">Puzzle</option>
<option value="Platformer">Sports</option>
<option value="Platformer">Strategy</option>
</select>
Upvotes: 0
Views: 5955
Reputation: 171
added the search feature also.
filteredGames () {
const self = this;
//for searching
if(this.search.length > 0){
return self.pdList.filter(function(game) {
console.log(game.title)
return game.title.toLowerCase().indexOf(self.search.toLowerCase()) >= 0;
});
}else{
if (self.currentFilter === 'all') {
return self.pdList;
} else {
return self.pdList.filter(function(game) {
return self.currentFilter === game.genre;
});
}
}
}
Upvotes: 0
Reputation: 804
You can try this approach as well after correcting the syntax issues as mentioned by @Naiful.
Template :
<div id="app">
<h2>Game Lister:</h2>
<ol>
<li v-for="game in filteredGames">
{{game.genre}}
</li>
</ol>
<select v-model="currentFilter">
<option value="all">all</option>
<option value="Platformer">Platformer</option>
<option value="Platformer">Puzzle</option>
<option value="Platformer">Sports</option>
<option value="Platformer">Strategy</option>
</select>
</div>
You can then put a watch on your currentFilter
model and invoke your filterByGenre
function to update filteredGames
.
VueJs Code :
new Vue({
el: "#app",
data (){
return {
currentFilter:"all",
filteredGames : [],
pdList:[{
"title": "Double Dragon: Neon",
"url": "/games/double-dragon-neon/xbox-360-131320",
"platform": "Xbox 360",
"score": 3,
"genre": "Fighting",
"editors_choice": "N",
"release_year": 2012
},
{
"title": "Guild Wars 2",
"url": "/games/guild-wars-2/pc-896298",
"platform": "PC",
"score": 9,
"genre": "RPG",
"editors_choice": "Y",
"release_year": 2012
}]
}
},
created (){
this.filterByGenre();
},
watch : {
'currentFilter' (){
this.filterByGenre();
}
},
methods: {
filterByGenre (){
this.filteredGames = [];
if(this.currentFilter == "all"){
this.filteredGames = this.filteredGames.concat(this.pdList);
}else{
this.filteredGames = this.pdList.filter(game => game.genre == this.currentFilter);
}
}
}
});
P.S. - In your vue code, data should be a function which returns an object
like recommended in VueJS official documentation.
Upvotes: 0
Reputation: 1220
The idea isn't a correct one. Some flaws in the code:
In Template:
div#app
- will result select in not being shownIn ViewModel:
pdList
in data()
has started with [,
- which will break the codeThe solution would be:
Template
<div id="app">
<h2>Game Lister:</h2>
<ol>
<li v-for="game in filteredGames">{{game.title}}</li>
</ol>
<select v-model="currentFilter">
<option value="all">all</option>
<option value="Fighting">Fighting</option>
<option value="RPG">RPG</option>
</select>
</div>
ViewModel
data: {
currentFilter: "all",
pdList: [{
"title": "Double Dragon: Neon",
"url": "/games/double-dragon-neon/xbox-360-131320",
"platform": "Xbox 360",
"score": 3,
"genre": "Fighting",
"editors_choice": "N",
"release_year": 2012
}, {
"title": "Guild Wars 2",
"url": "/games/guild-wars-2/pc-896298",
"platform": "PC",
"score": 9,
"genre": "RPG",
"editors_choice": "Y",
"release_year": 2012
}]
},
computed: {
filteredGames () {
const self = this;
if (self.currentFilter === 'all') {
return self.pdList;
} else {
return self.pdList.filter(function(game) {
return self.currentFilter === game.genre;
});
}
}
}
Upvotes: 3
Reputation: 3162
A method invocation will always run the function whenever a rerender happens. To know that it depends on this.pdList, you don't need to parse it in.
HTML
<li v-for="game in filteredGames()">
{{game.genre}}
</li>
Vuejs
filteredGames:function(){
console.log("inside filtergames");
if(this.currentFilter == "all"){
return this.pdList;
} else {
return this.pdList.filter(function(game){
console.log(this.currentFilter);
return game.genre == this.currentFilter;
});
}
}
Upvotes: 0