I'm fetching data from the Star Wars API, more specifically people and it's working. I want to create a search filter function that as I start typing, only the names with those letters appear. This is my code to fetch the data in StarWarsPeopleComponent.vue file:
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<input type='text' v-model="search" placeholder='Search people...'/><br>
{{ getAllStarWarsPeople() }}
<ul>
<li v-for="person in people.results">
{{ person.name }}
</li>
</ul>
</div>
</div>
</div>
</template>
<script>
export default {
name: "StarWarsPeopleComponent",
data() {
return {
people: [],
search: ''
}
},
mounted() {
console.log('Component mounted.')
},
methods:{
getAllStarWarsPeople() {
fetch("https://swapi.co/api/people/")
.then(response=>response.json())
.then(data=>{
this.people=data;
})
}
}
}
</script>
Note how I access the data in the v-for with people.results.
Here is my component updated with a computed function that I created but now the data isn't showing and I get this error:
[Vue warn]: Error in render: "TypeError: this.people.filter is not a function".
I'm pretty new to Vue js and I don't know what this means or how to fix it. Can anyone help?
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<input type='text' v-model="search" placeholder='Search people...'/><br>
{{ getAllStarWarsPeople() }}
<ul>
<li v-for="person in filteredPeople">
{{ person.name }}
</li>
</ul>
</div>
</div>
</div>
</template>
<script>
export default {
name: "StarWarsPeopleComponent",
data() {
return {
people: [],
search: ''
}
},
mounted() {
console.log('Component mounted.')
},
methods:{
getAllStarWarsPeople() {
fetch("https://swapi.co/api/people/")
.then(response=>response.json())
.then(data=>{
this.people=data;
})
}
},
computed: {
filteredPeople: function() {
return this.people.filter((person) => {
return person.name.match(this.search);
});
}
}
}
</script>
use "created()" to call getAllStarWarsPeople() when component is loaded.
add getAllStarWarsPeople as "@keyup" on input field.
try this:
<template>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<input
type="text"
v-model.trim="search"
placeholder="Search people..."
@keyup="getAllStarWarsPeople"
/><br />
<ul>
<li v-for="person in people" :key="person.id">
{{ person.name }}
</li>
</ul>
</div>
</div>
</div>
</template>
<script>
export default {
name: "StarWarsPeopleComponent",
data() {
return {
people: [],
search: ""
};
},
mounted() {
console.log("Component mounted.");
},
methods: {
getAllStarWarsPeople() {
fetch("https://swapi.co/api/people/")
.then(response => response.json())
.then(res => {
if (this.search) {
this.people = res.results.filter(people =>
people.name.toLowerCase().includes(this.search.toLowerCase())
);
} else {
this.people = res.results;
}
});
}
},
created() {
this.getAllStarWarsPeople();
}
};
</script>
JsFiddle here:
new Vue({ el: "#app", data: { people: [], search: "" }, methods: { getAllStarWarsPeople() { fetch("https://swapi.co/api/people/") .then(response => response.json()) .then(res => { if (this.search) { this.people = res.results.filter(people => people.name.toLowerCase().includes(this.search.toLowerCase()) ); } else { this.people = res.results; } }); } }, created() { this.getAllStarWarsPeople(); } })
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> <input type="text" v-model.trim="search" placeholder="Search people..." @keyup="getAllStarWarsPeople" /><br /> <ul> <li v-for="person in people" :key="person.id"> {{ person.name }} </li> </ul> </div>
You can use like
computed: { filteredPeople() { if (this.people) { return this.people.filter((person) => { return person.name.match(this.search); }); } return false; } }
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.