user2953989
user2953989

Reputation: 2979

Creating a dropdown filter for JSON data in Vue

I want to use a dropdown that filters through my JSON data and displays different JSON data items if they match the dropdown option. So far I've managed to get it so a function runs when someone selects an item from the dropdown menu, but i'm unsure why the filter doesn't work, as i'm not getting any errors in the console or in WebStorm.

Here's an example of my code and JSON data:

<template>
    <b-container id="product-list">
        <b-row>
            <b-col>
                <div>
                    <b-dropdown id="ddown4" text="Product Type" class="m-md-2">
                        <b-dropdown-item @click="FilterProducts" v-model="selectedCategory">4.5</b-dropdown-item>
                        <b-dropdown-item @click="FilterProducts" v-model="selectedCategory">10.5</b-dropdown-item>
                    </b-dropdown>
                </div>
            </b-col>
        </b-row>
        <hr>
        <b-row>
            <b-col md="4" v-for="product in Products">
                <img class="img-fluid" :src="product.image"/>
                <h5>{{ product.product_name }}  </h5>
                <p class="original-price strikethrough">£{{ product.original_price }}</p>
                <p>£{{ product.final_price }}</p>
            </b-col>
        </b-row>
    </b-container>
</template>
<script>
    import Axios from "axios";

    export default {
        name: 'Products',
        data() {
            return {
                Products: null,
                selectedCategory: ''
            }
        },
        mounted() {
            Axios.get('/products.json')
                .then(response => (this.Products = response.data.data))
        },
        methods: {
            FilterProducts() {
                var vm = this;
                var category = vm.selectedCategory;

                if(category === '') {
                    return vm.Products;
                } else {
                    return vm.Products.filter(function(product) {
                        return product.attributes.tog === category;
                    });
                }
            }
        }
    }
</script>

JSON data example:

"data": [
    {
      "id": "83",
      "product_name": "TV",
      "category": "Clearance",
      "original_price": "139.0000",
      "final_price": "105.0000",
      "attributes": {
        "size": "260x220",
        "tog": "10.5 tog"
      }
      "url": "/tv"
    }

Upvotes: 7

Views: 6585

Answers (1)

calmar
calmar

Reputation: 1959

Your computed method is reactive to selectedCategory and no need to call @click as your are using v-model.

<template>
    <b-container id="product-list">
        <b-row>
            <b-col>
                <div>
                    <b-dropdown id="ddown4" text="Product Type" class="m-md-2">
                        <b-dropdown-item v-model="selectedCategory">4.5</b-dropdown-item>
                    </b-dropdown>
                </div>
            </b-col>
        </b-row>
        <hr>
        <b-row>
            <b-col md="4" v-for="product in filteredProducts">
                <img class="img-fluid" :src="product.image"/>
                <h5>{{ product.product_name }}  </h5>
                <p class="original-price strikethrough">£{{ product.original_price }}</p>
                <p>£{{ product.final_price }}</p>
            </b-col>
        </b-row>
    </b-container>
</template>
<script>
    import Axios from "axios";

    export default {
        name: 'Products',
        data() {
            return {
                Products: null,
                selectedCategory: ''
            }
        },
        mounted() {
            Axios.get('/products.json')
                .then(response => (this.Products = response.data.data))
        },
        computed: {
            filteredProducts() {

                if(this.selectedCategory === '') {
                    return this.Products;
                } else {
                    const category = this.selectedCategory;
                    return this.Products
                               .filter((product) => product.attributes.tog === category)
                }
            }
        }
    }
</script>

Upvotes: 8

Related Questions