Access the filtered data with Vuex and Firestore to display the results

I am looking to enhance my project by implementing a filtering feature. I currently have a buttons component that will trigger the filter search.

When I click the restaurant button, it should display the shops with a "Restaurant" value in Firestore.

Conversely, when I click the supermarket button, it should show the shops with a "Supermarket" value in Firestore.

Currently, I am using Vuex to retrieve data from "getMenuItems" using mapGetters in Result.vue.

In Buttons.vue, I have added methods to trigger mutations. For instance, pressing the restaurant button will push restaurant data into "restaurantItems" in menu.js.

My goal is for Result.vue to read "restaurantItems" instead of "getMenuItems" when the restaurant button is pressed.

I attempted to use an if statement in the computed property of Result.vue but couldn't find a solution.

If my approach is incorrect, please guide me on the correct way to achieve this.

Buttons.vue

<template>
    <div>
        <section class="button-section">
            <div class="d-flex buttons">
                <b-button class="supermarket" @click.prevent="showSupermarket">Supermarket</b-button>
                <b-button class="restaurant" @click.prevent="showRestaurant">Restaurant</b-button>
        </div>
        </section>
    </div>
</template>

<script>
import fireApp from '@/plugins/firebase'
const firebase = require("firebase");
require("firebase/firestore");
const db = firebase.firestore();
import { mapGetters } from 'vuex'
import store from '../store'

    export default {
        name: 'Buttons',
        data() {
            return {
                supermarket: "",
                restaurant: ""
            }
        },
        methods: {
            showSupermarket() {
                const supermarketRef = db.collection('Product').where('type', '==', "Supermarket")
                supermarketRef.get()
                    .then(snapshot => {
                    if (snapshot.empty) {
                    console.log('No matching documents.');
                    return;
                    }
                    snapshot.forEach(doc => {
                        const supermarket = doc.data()
                        console.log(supermarket)
                        this.supermarket = supermarket
                        //triger mutation here.
                        this.$store.commit('showSupermarketResult', this.supermarket)
                        //console.log(doc.id, '=>', doc.data());
                    });
                })
                .catch(err => {
                    console.log('Error getting documents', err);
                });
            },
            showRestaurant() {
                const restaurantRef = db.collection('Product').where('type', '==', "Restaurant")
                restaurantRef.get()
                    .then(snapshot => {
                    if (snapshot.empty) {
                    console.log('No matching documents.');
                    return;
                    }
                    snapshot.forEach(doc => {
                        const resutaurant = doc.data()
                        console.log(resutaurant)
                        this.resutaurant = resutaurant
                        this.$store.commit('showRestaurantResult', this.resutaurant)
                        //console.log(doc.id, '=>', doc.data());
                    });
                })
                .catch(err => {
                    console.log('Error getting documents', err);
                });
            },
        }
    }
</script>

Result.vue

<template>
    <div>
    <Navbar />
    <Map />
    <Buttons />
    
    <div class="main">
        
        <section class="cards">
        <div class="card" v-for="(item, index) in getMenuItems" :key="index">
            <div class="card-icons" v-if="item.quantity > 0">
            <div class="card-icon">
            <div class="card__image-container" v-for="(sample, index) in item.sample" :key="index">
                <!-- <router-link to="/product"> -->
                <router-link :to="{name:'Product',params:{id:item.id}}">
                <img
                :src="sample"
                alt="Detailed image description would go here."
                />
                </router-link>
                <div class="card__content">
                    <div class="card__info">
                        <span class="text--medium">{{ item.business }}</span>
                        <span class="card__distance text--medium">{{ item.quantity }} left</span>
                    </div>
                </div>
            </div>
            </div>
            <div class="icons">
            <div class="time">
                <span>until<br>{{ item.limitObject }}</span>
                </div>
                <div class="fav">
                <span>Heart</span>
                </div>
                <div class="price">
                <span>{{ item.initial }}<br>{{ item.sale }}</span>
                </div>
            </div>
            </div>
        </div>
        </section>
    </div>
    </div>
</template>

<script>
import axios from 'axios';
import Navbar from "@/components/Navbar.vue";
import Buttons from "@/components/Buttons.vue";
import Map from "@/components/Map.vue";
import fireApp from '@/plugins/firebase'
const firebase = require("firebase");
require("firebase/firestore");
const db = firebase.firestore();
import { mapGetters } from 'vuex'


    export default {
        name: "UserLocation",
        data() {
            return {
                address: "",
                error: "",
                spinner: false
            }
        },
        components: {
            Navbar,
            Map,
            Buttons
        },
        created() {
            //vuexfire
            const dbMenuRef = db.collection('Product')
            this.$store.dispatch('setMenuRef', dbMenuRef)
        },        
        computed: {
            ...mapGetters([
                'getMenuItems'
            ])
        },
        methods: {
            
        }
    }
</script>

menu.js

import { firestoreAction } from 'vuexfire'
import fireApp from '@/plugins/firebase'
const firebase = require("firebase");
require("firebase/firestore");
const db = firebase.firestore();

const dbMenuRef = db.collection('Product')

const state = {
    menuItems:[],
    supermarketItems:[],
    restaurantItems: [],
    store:[]
}

const getters = {
    getMenuItems: state => state.menuItems,
    supermarketItems: state => state.supermarketItems,
    restaurantItems: state => state.restaurantItems
}

const mutations = {
    showSupermarketResult(state, supermarket) {
        state.menuItems.push(supermarket);
    },
    showRestaurantResult(state, restaurant) {
        state.restaurantItems.push(restaurant);
    },
}

const actions = {
    setMenuRef: firestoreAction(context => {
        return context.bindFirestoreRef('menuItems', dbMenuRef)
    }),
    
}

export default {
    state,
    mutations,
    getters,
    actions
}

Answer №1

To enhance the code quality, a refactoring process is recommended for various sections in the query. Some of the areas needing attention are:

Buttons.vue: Enhancement of button functionalities

<b-button class="supermarket" @click.prevent="showCollection('supermarket')">Supermarket</b-button>
<b-button class="restaurant" @click.prevent="showCollection('restaurant')">Restaurant</b-button>

Buttons.vue: Improving method structures

methods: {
    showCollection(type) {
        this.$store.dispatch('setCollectionType', type)
    }
}

menu.js: Transitioning firestore operations into actions with side effects

const state = {
    ...,
    currentType: 'menu'
}
const mutations = {
    ...,
    setCurrentType(state, type) {
        state.currentType = type
    }
}
const actions = {
    ...
    setCollectionType: ({ commit, state }, type) {
        commit('setCurrentType', type)
        const mutations = {
            supermarket: 'showSupermarketResult',
            restaurant: 'showRestaurantResult'
        }
        const states = {
            supermarket: 'supermarketItems',
            restaurant: 'restaurantItems'
        }
        if (state[states[type]].length) return
        const collectionRef = db.collection('Product').where('type', '==', type)
        collectionRef.get()
            .then(snapshot => {
                if (snapshot.empty) {
                    console.log('No matching documents.');
                    return;
                }
                snapshot.forEach(doc => {
                    const data = doc.data()
                    commit(mutations[type], data)
                });
            })
            .catch(err => {
                console.log('Error getting documents', err);
            });
        },
    }
}

Result.vue: Lastly, revamp the presentation of results for better visibility

<div class="card" v-if="currentType === 'supermarket'" v-for="(item, index) in supermarketItems" :key="index">
    <!-- Display details for supermarket items-->
</div>
<div class="card" v-if="currentType === 'restaurant'" v-for="(item, index) in restaurantItems" :key="index">
    <!-- Display details for restaurant items-->
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

utilizing an ajax request to clear the contents of the div

When I click on Link1 Button, I want to use ajax to empty the contents in the products_list div <button type="w3-button">Link1</button> I need help with creating an ajax call that will clear the products in the product_list when the link1 but ...

Menu that sorts items based on a specified range of values entered by the user

I'm looking to implement a customized filtering dropdown menu, similar to the one showcased on this website Currently, I have functioning filters that can select items based on a specific category. However, I want to enhance the functionality by inc ...

Adaptable material for collapsible panels

I'm facing a challenge with implementing an accordion menu. My goal is to have a 4 column layout that transforms into an accordion menu when the browser width is less than 600px. It almost works as intended, but there's a glitch. If you start at ...

Updating NPM packages versions is currently restricted

I'm in the process of creating a Next.JS application using create-next-app. However, I've noticed that in the package.json file it lists the following dependencies: "eslint": "8.43.0", "eslint-config-next": &quo ...

"Encountering a strange issue where submitting a form with Jquery and AJAX in Rails does not work as expected, causing the index

Currently facing a unique issue with a jQuery/Ajax HTML update form. The application in question is a single-page TODO App that utilizes a Rails controller, where all changes to the DOM are made through jQuery/Ajax. After rendering the TODOs on the page v ...

Utilizing the Google Site Verification API through a Firebase cloud function

I am attempting to utilize the Google Site Verification API from a Firebase function using Node.js. The README found in the google-api-nodejs-client repository on Github advises using the default application method over manually creating an OAuth2 client, ...

What is the procedure for verifying the type of an element using chai?

Is there a way to determine if an element is either an "a" tag or a "div" tag? I've tried the following code, but it's not working as expected: it('has no link if required', () => { const wrapper = shallow(<AssetOverlay a ...

Totally clueless when it comes to JSON

After diving into tutorials on JSON, the structure and syntax are finally clicking for me. However, I'm currently working on a project that requires a GET, and it seems like JSON could help with this. I've come across comparisons of JSON and AJA ...

Challenges arising from the intersection of Vue's scoped styles and Bootstrap

Currently, I am working on developing an embedded plugin using Vue.js. During the development phase, this plugin is integrated into a html page filled with placeholder text that loads Bootstrap. I recently discovered that one of the elements within my plu ...

Having trouble displaying values from nested JSON in a datatable

Response from server : ["{\"CLIENT\":[{\"tranche\":\"1-4\",\"prix\":\"65.96\",\"currency\":\"E\"}],\"DISTRIBUTEUR\":[{\"tranche\":\"1-4\",\"prix\ ...

Tips for preventing text from changing its padding within a div when reducing the width and height dimensions

I am facing an issue with a div inside another div. The child div contains text, and when I apply animation to decrease the width and height, the text inside gets reset according to the new size. While I understand why this happens, I want to find a way to ...

There was an issue with the Discord.js (v12) Giveaway Command that resulted in an error stating "Error: Cannot read property 'hasPermission' of undefined"

Hey everyone, I'm trying to develop my own Discord bot and I want to add a giveaway command to it. I found an example code online that I tried to implement, but unfortunately, it's not working as expected... const ms = require('ms'); c ...

Following a Node/Npm Update, Sails.js encounters difficulty locating the 'ini' module

While developing an application in Sails.js, I encountered an authentication issue while trying to create user accounts. Despite my efforts to debug the problem, updating Node and NPM only resulted in a different error. module.js:338 throw err; ...

"Utilizing jQuery's AJAX POST method with PHP is successful, while using XMLHttpRequest is not yielding

Currently in the process of revamping my existing code to transition from jQuery's AJAX function to using XMLHttpRequest in vanilla JS. My understanding is that the following code snippets should be equivalent. However, while the jQuery version functi ...

What is the most efficient way to retrieve key pair values of separate elements in an array with just one API request?

The API I am working with returns an array of elements, each containing multiple key-value pairs. An example of a similar API response can be seen here: , where an array of poems is returned. [ { "title": "...." "content": "..." "url" : "..." } ...

Search for a DIV element within iMacro on a consistent basis

I recently started using iMacro and encountered an issue while recording a script that involved clicking on a pop-up when it appeared on the screen. The problem arose because the pop-up only appears when a new event is posted. Therefore, when I initially c ...

I require assistance in understanding how to successfully implement ParseINT with (row.find)

enter image description hereHow To Utilize ParseINT Using row.find(). I Attempted This Code But It Doesn't Work. This is My Code : function update_qty() { var row2 = $(this).parents('.item-row'); var price2 = row2.find(parseInt($ ...

Issues with Toggling Visibility in HTML, CSS, and Javascript

Currently, I am working on a website and following a tutorial called "Creating Slideshow using HTML, CSS, and Javascript" by W3Schools. In the project, I want to hide the thumbnail images located at the bottom and the navigation arrows initially and have t ...

Unable to transfer an array from getStaticProps method in Next.js

Whenever I pass a JSON array from getStaticProps in Next.js, I encounter this specific error message when trying to access it. TypeError: Cannot read property 'contentBody' of undefined module.exports../pages/[author]/[article].js.__webpack_expo ...

You cannot convert a function to a string while utilizing axios get in nuxtServerInit

While attempting to connect my app to the backend using Udemy's Nuxt.js course, I encountered a GET http://localhost:3000/ 500 (Internal Server Error) on the client side with the following code: import Vuex from 'vuex'; import axios from &a ...