I have loaded a data from API and displayed here with VueJS. I have users information inside users[]
array. I also have users with two types of plan: basic_plan
and standard_plan
. Currently it shows all users.
Now I want to apply filters equally to this example: https://codepen.io/marn/pen/jeyXKL?editors=0010
I also got an error filter
not defined
Filters:
<input type="radio" v-model="selectedItems" value="All" /> All
<input type="radio" v-model="selectedItems" value="basic_plan" /> Basic
<ul
v-for="(user, index) in selectedUser.data"
:key="index"
class="watchers divide-y divide-gray-200"
>
<li class="py-4">
<div class="mx-4 flex space-x-3">
<span
class="inline-flex items-center justify-center h-8 w-8 rounded-full bg-gray-500"
>
</span>
<div class="flex-1 space-y-1">
<h3 class="text-sm font-medium">
{{ user.name }}
</h3>
<div class="flex items-center justify-between">
<p class="text-sm font-medium text-indigo-500">
{{ user.plan }}
</p>
</div>
</div>
</div>
</li>
</ul>
</div>
</template>
<script
export default {
data() {
return {
users: [],
selectedItems:"All"
};
},
created() {
this. users();
},
methods: {
users {
axios
.get('api/users')
.then(response => {
this.users = response.data;
}
},
computed: {
selectedUser: function() {
if(this.selectedItems ==="All"){
return this.users
}else{
return this.users.data.filter(function(item) {
console.log(item)
return item.plan === this.selectedItems;
});
}
}
}
};
</script>
when All is selected vue dev tool shows this
selectedUser:Object //OBJECT SHOWING
data:Array[10]
links:Object
meta:Object
but when basic radio is selected vue shows this
selectedUser:Array[1] //ARRAY SHOWING
0:Object
price:"10"
plan:"basic_planl"
2 Answers 2
If you want to filter out specific users you must apply the "filter" function to the users variable like this:
this.users.filter(...)
With this function you then can filter the users based on their plan like this:
this.users.filter((user) =>
user.plan === this.selectedItems;
});
For a modern approach I used an arrow function. And without using curly brackets the statement inside the function is returned by default, so that's why there is no "return" statement.
Comments
Try this way instead, as you are already using v-for
in your HTML, you can conveniently filter out users without any more loops, if you are getting value as "basic_plan" in the "user.plan" key.
Also, I think that you should move your v-for
to <li>
tag instead of <ul>
along with the validation on <ul>
if there are no users in the array.
<template>
<div>
<input type="radio" v-model="selectedItems" value="All" /> All
<input type="radio" v-model="selectedItems" value="basic_plan" /> Basic
<ul v-if="selectedUser.data.length" class="watchers divide-y divide-gray-200">
<li v-for="(user, index) in selectedUser.data" :key="index" class="py-4">
<div v-if="filterUser(user)" class="mx-4 flex space-x-3">
<span class="inline-flex items-center justify-center h-8 w-8 rounded-full bg-gray-500"></span>
<div class="flex-1 space-y-1">
<h3 class="text-sm font-medium">
{{ user.name }}
</h3>
<div class="flex items-center justify-between">
<p class="text-sm font-medium text-indigo-500">
{{ user.plan }}
</p>
</div>
</div>
</div>
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
users: [],
selectedItems:"All"
};
},
methods: {
filterUser(user){
if(this.selectedItems === 'All'){
return true;
}
if(this.selectedItems === 'basic_plan'){
return this.selectedItems === user.plan;
}
}
},
}
</script>
computed.selectedUser()
return this.users.data.filter
intoreturn this.users.filter
, because you have already applied the data property from your response ontothis.users
.