david001's avatar

simple filter with vue js

Hi, I have loaded a data from api and displayed here with vue. I have users information I users[] array I have users with two types of plan , basic_plan and standard_plan . currently it shows all user on view and now I want to apply filters I am taking example from here: https://codepen.io/marn/pen/jeyXKL?editors=0010



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"
0 likes
4 replies
piljac1's avatar

According to your code, this.users is an object and by doing this.user.data.filter(...) you return an array (the filtered data array). If you want to keepthe same structure and only update the data array, you could do the following:

const data = this.users.data.filter(function(item) {
    console.log(item)
    return item.plan === this.selectedItems;
});

return { ...this.users, ...data };

Or even cleaner:

const data = this.users.data.filter(item => item.plan === this.selectedItems);

return { ...this.users, ...data };
david001's avatar

@piljac1 got error: [Vue warn]: Error in render: "TypeError: Cannot read property 'selectedItems' of undefined"

found in


    computed: {
        selectedUser: function() {
            if (this.selectedItems === "All") {
                return this.users;
            } else {
                const data = this.users.data.filter(function(item) {
                    console.log(item);
                    return item.plan === this.selectedItems;
                });

                return { ...this.users, ...data };
            }
        }
    }
apex1's avatar

You lose this binding in your filter callback.

piljac1's avatar

@apex1 Is right. I just copy pasted your filtering code, but didn't realize you were using the older anonymous function syntax. You need to use the second alternative I posted (arrow function), so this refers to the component's context and not the inside scope of the function (which is the case with older anonymous function syntax).

Else, if you want to keep your console log, you can do the folowing:

const data = this.users.data.filter(item => {
    console.log(item);
    return item.plan === this.selectedItems;
});

Please or to participate in this conversation.