I need some help. I have an array allGames
of objects received as a prop from the parent. I need to filter this array based on its objects properties ( venue, date, price
) and so on. The filter values will be entered by the user in either a checkbox, a dropdown or something else. I need these filters to work together.
For that I am using two extra arrays: one called filteredGames
to hold the games to be displayed after filtering and another one called searchTerm
that updates as the inputs are entered.
I managed to filter properly using the following code:
<input type="text" name="date" v-model="searchTerm.date">
<input type="text" name="venue" v-model="searchTerm.venue">
<input type="text" name="price" v-model="searchTerm.price">
export defaults {
props: {
allGames: {
type: Array,
required: true
}
},
data: function () {
return {
filteredGames: [],
searchTerm: {
venue: '',
date: '',
price: ''
}
}
},
watch: {
searchTerm: {
handler: function (val) {
this.filterGames()
this.$emit('input', val)
},
deep: true
}
},
methods: {
filterGames: function () {
if (this.filteredGames.length === 0) { this.filteredGames = this.allGames }
if (this.searchTerm.venue) { this.searchTerm.venue = this.searchTerm.venue.toLowerCase() }
if (this.searchTerm && this.filteredGames) {
this.filteredGames = this.allGames.filter(game => {
return (
game.venue.toLowerCase().search(this.searchTerm.venue) >= 0 &&
game.date.search(this.searchTerm.date) >= 0 &&
game.price.search(this.searchTerm.price) >= 0
)
})
}
}
}
}
The problem I'm having is that not all of the original objects' properties are filled. For example, a game may have its price
column empty. When that happens I get Error in callback for watcher "searchTerm": "TypeError: game.price is null"
and the search doesn't work at all.
Is there a way to add an if
statement inside return? Something like if (game.price) { game.price.search(this.searchTerm.price) >= 0 }
?
I couldn't find a way to make it work. If it's not possible is there an alternative?
I appreciate any help.
You can do this, only apply the search if the property is truthy like this:
This is called
Short-circuit evaluation
return (
(game.venue && game.venue.toLowerCase().search(this.searchTerm.venue) >= 0) &&
(game.date && game.date.search(this.searchTerm.date) >= 0) &&
(game.price && game.price.search(this.searchTerm.price) >= 0)
);
It works because in JavaScript, true && expression
always evaluates to expression
, and false && expression
always evaluates to false.
Edit Using ||
to return true even if 1 search matches:
return (
(game.venue && game.venue.toLowerCase().search(this.searchTerm.venue) >= 0) ||
(game.date && game.date.search(this.searchTerm.date) >= 0) ||
(game.price && game.price.search(this.searchTerm.price) >= 0)
);
Edit 2 To filter only and all the values entered by the user and ignore the others:
return (
(!game.venue || game.venue.toLowerCase().search(this.searchTerm.venue) >= 0) &&
(!game.date || game.date.search(this.searchTerm.date) >= 0) &&
(!game.price || game.price.toString().search(this.searchTerm.price) >= 0)
);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.