I want to make a search component that receives an object and then filters it by user input. Then pass it again to parent to show what i filtered. (Nuxt)
// Parent component
<AppSearch :bookmarks="bookmarks" />
...
bookmarks = [ { "title": "Facebook", "url": "https://facebook.com" }, { "title": "Google", "url": "https://google.com/" } ]
// Child search component
<template>
<input type="text" v-model="searchQuery"> </input>
</template>
<script>
export default {
props: ['bookmarks'],
data() {
return {
searchQuery: null,
}
},
computed: {
filteringBookmarks:{
get: function() {
if(this.searchQuery){
return this.bookmarks.filter(data => data.title.toLowerCase().includes(this.searchQuery.toLowerCase()))
} else{
return this.bookmarks;
}
}
}
},
watch: {
filteringBookmarks(newValue) {
console.log(`yes, computed property changed: ${newValue}`); // <--- INFINITES MESSAGES
this.$emit('update:bookmarks', filteringBookmarks)
}
},
}
</script>
I've tried another ways but always ends in the same spot, whole website freezing. Its seems like never stop refreshing "bookmarks". Maybe is a circular problem?
The best way to avoid this circular issue is to watch the searchQuery
<script>
export default {
props: ['bookmarks'],
data() {
return {
searchQuery: null,
}
},
watch: {
searchQuery(newValue) {
let filteringBookmarks=[]
if(newValue){
filteringBookmarks=this.bookmarks.filter(data => data.title.toLowerCase().includes(this.searchQuery.toLowerCase()))
}else{
filteringBookmarks=this.bookmarks;
}
this.$emit('update:bookmarks', filteringBookmarks)
}
},
}
</script>
You are emitting a computed value to the parent component, and the parent updates the bookmarks and pass it as a prop to the child component which makes the computed property to be updated and since you have a watcher on the computed property, it will again emits it's new value causing an infinite loop.
A solution can be to emit search query itself and then filter the results on the parent element.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With