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("/")
.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 ponent updated with a puted 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("/")
.then(response=>response.json())
.then(data=>{
this.people=data;
})
}
},
puted: {
filteredPeople: function() {
return this.people.filter((person) => {
return person.name.match(this.search);
});
}
}
}
</script>
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 ponent updated with a puted 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;
})
}
},
puted: {
filteredPeople: function() {
return this.people.filter((person) => {
return person.name.match(this.search);
});
}
}
}
</script>
Share
asked Jan 16, 2020 at 1:35
Ryan SacksRyan Sacks
5241 gold badge15 silver badges48 bronze badges
2
-
in vue,
this
cannot be used in foreign function. use filter function like in Evan answer instead. – Khairul Habib Commented Jan 16, 2020 at 2:07 -
swapi is not really a good option here, as is no possibility to search by keyword. That would not be a problem if swapi in fact returns all people by that request, but it does not, it's paging it, so you would need to make subsequent requests to actually get all people to filter from, as
people
url just returns 10 people and gives you anext
property like:"next": "https://swapi.co/api/people/?page=2",
then page 3 etc. Consider using another free api instead unless you want to fire multiple requests and store all people in an array to filter from :) – AVJT82 Commented Jan 16, 2020 at 17:05
2 Answers
Reset to default 5use "created()" to call getAllStarWarsPeople() when ponent 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.dev/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.dev/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./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
puted: {
filteredPeople() {
if (this.people) {
return this.people.filter((person) => {
return person.name.match(this.search);
});
}
return false;
}
}