Refine the Vuex state with a filter

Currently, I've progressed in my Vue development journey and started exploring the implementation of Vuex for state management.

In the past, I had a main Vue component that handled search functionality, an array of items to iterate over, and the iteration process itself.

However, when I attempted to divide the single component into multiple components (search, item list, and individual item), I noticed that I couldn't modify reactive properties from within a child component.

Now, I'm contemplating how to filter my list of items. Do I achieve this through state mutation or by using computed properties in the child component?

This was my previous approach:

export default {
    components: { Job },
    data() {
        return {
          list: [],
          categories: [],
          states: states,
          countries: countries,
          keyword: '',
          category: '',
          type: '',
          state: '',
          country: '',
          loading: true
        }
  },
  mounted() {
    axios.get('/api/cats.json')
        .then(response => 
            this.categories = response.data.data
        )
    axios.get('/api/jobs.json')
        .then(function (response) {
            this.list = response.data.data;
            this.loading = false;
        }.bind(this))
  },
  computed: {
    filteredByAll() {
      return getByCountry(getByState(getByType(getByCategory(getByKeyword(this.list, this.keyword), this.category), this.type), this.state), this.country)
    },
    filteredByKeyword() {
      return getByKeyword(this.list, this.keyword)
    },
    filteredByCategory() {
      return getByCategory(this.list, this.category)
    },
    filteredByType() {
      return getByType(this.list, this.type)
    },
    filteredByState() {
        return getByState(this.list, this.state)
    },
    filteredByCountry() {
        return getByCountry(this.list, this.country)
    }
  }
}

function getByKeyword(list, keyword) {
  const search = keyword.trim().toLowerCase()
  if (!search.length) return list
  return list.filter(item => item.name.toLowerCase().indexOf(search) > -1)
}

function getByCategory(list, category) {
  if (!category) return list
  return list.filter(item => item.category == category)
}

function getByType(list, type) {
  if (!type) return list
  return list.filter(item => item.type == type)
}

function getByState(list, state) {
    if(!state) return list
    return list.filter(item => item.stateCode == state)
}

function getByCountry(list, country) {
    if(!country) return list
    return list.filter(item => item.countryCode == country)
}

My dilemma now is whether the filtering should be done within the search component itself or as a mutation within the state?

Answer №1

Is it better to apply filters within the search component or as a mutation within state?

I'm unsure why you would want to mutate your `state` for filtering. What if additional filters need to be applied in the future? I recommend using getters for each filter within the computed properties of your components.

You can organize these filter methods in a separate JavaScript file for reusability.

export function getByKeyword(list, keyword) {
  const search = keyword.trim().toLowerCase()
  if (!search.length) return list
  return list.filter(item => item.name.toLowerCase().indexOf(search) > -1)
}

// Other filter functions...

These getter functions can then be utilized in your Vuex store:

// someStoreModule.js

import {getByKeyword, getByCategory, getByType, getByState, getByCountry} from 'path/to/these/functions/file.js'

state: {
  // Your state properties here
},
getters: {
  // Getter definitions here utilizing the filter functions
}

Finally, your components can access the filtered data by mapping the getters:

import { mapGetters } from 'vuex'

export default {
  ...
  computed: {
    ...mapGetters([
     'filteredByKeyword',  
     'filteredByCategory', 
     // More mapped getters...
    ])
  }
  ...
}

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

Customize specific styles for individual divs one at a time (without the use of jQuery)

Can you assist me with this issue? I am trying to display the <span class="badge badge-light"><i class="fa fa-check-circle"></i></span> tag (initially set to "visibility: hidden") when clicking on a div with the class "role-box". He ...

How to transform multi-dimensional arrays to JSON format using JavaScript (and maybe jQuery)

Currently facing a Javascript dilemma where data storage is essential in the following format: MainArray(Array(JavaScript Object, JavaScript Object, etc etc..), Array(JavaScript Object, JavaScript Object, etc etc..), etc etc..) The main array consists of ...

Exploring the Haversine Formula and Geolocation Integration in AngularJS

I am currently developing an application that will organize locations based on either name or distance from the user. Everything is functioning properly except for retrieving the distance. I believe I should be able to obtain the user's coordinates th ...

Exploring different ways to navigate JSON data dynamically and efficiently modify it

I have a JSON data structure resembling a map. var map = { level1 : { x : {name:'level1 x' , }, y : {name:'level1 y'} }, level2 : { x : {name:'level2 x&a ...

When hovering over certain transitioning elements in a D3JS chart, the animation execution is paused if other elements are also in the process of transitioning

Currently, I have been designing a horizontal bar chart and experimenting with transitions on various elements like rect and circle. The transitions are applied to attributes like width and r to achieve the desired effect. Everything seems to be working fi ...

A step-by-step guide to loading a .php file via Ajax using JQuery when an item is selected from a dropdown

I have successfully populated a dropdown list using PHP from a database on the page named admin.php. Now, I am utilizing JQuery with Ajax functionality to display information when a surname is clicked from the dropdown menu. The goal is to call employerP ...

Translating Vue components within an asp.net core web application

I recently inherited a Web App at work that was built in ASP.Net Core 2.2 with Views created using Razor and Vue. I've been tasked with adding multilanguage support to the app, so I have already created all the resx files and added IViewLocalizer to t ...

How to detect a click event in any area of an Angular2

Hey there, I'm new to typescript and angular 2 and I've encountered an error in my code. Can someone lend me a hand in fixing this? import { Component, HostListener } from '@angular/core' export class TooltipComponent { public sh ...

How can I access and retrieve a local variable using geolocation in HTML5 and the Google Maps API?

Seeking assistance with a coding dilemma: I need to retrieve the geolocation position for use in my calcRoute function. The goal is to set the geolocation as the starting point. Below is the code snippet: function calcRoute(){ var pos; navigator.g ...

Error: The React Material-UI modal is encountering a type error where it cannot access the property 'hasOwnProperty' of an undefined value

Whenever I include a modal in one of my classes, I encounter this error. Error: Unable to access property 'hasOwnProperty' of undefined Here is a simple example where I am attempting to display a basic modal at all times. Any suggestions? I h ...

Could someone explain to me why searchQuery.value is coming up as undefined?

Within my development task, I am endeavoring to create a functional search icon on the header bar that allows users to input Pokémon names for searching purposes. Despite my efforts, I am consistently facing a console error message suggesting "searchQu ...

Using V-bind to assign multiple classes has never been easier

Is there a way to assign one of two classes to an element based on three possible input variables in my Vue.js code? <input type='text' class='inputwordtext' v-bind:class="{(wordupload.firstchoice.selected == 'Zinnenlijst' ...

Is it possible to execute this animation with a single click for repetitive playback?

CODEPEN const btt = document.querySelector('.btt'); btt.addEventListener('click', function(){ this.classList.toggle('anime'); }); Is there a way to achieve the desired effect with just one click? ...

What is the best way to generate script code dynamically on an HTML page depending on the environment?

I am facing a challenge with my asp.net application. I need to insert a dynamic script into the html section, and this script's value must change depending on the environment (TEST, QA, etc.). To illustrate, here is the script where DisplayValue is th ...

Exploring the Functionality of Using Multiple Middlewares in Vue.js 3

For my web app project using vue.js 3 and vue-router, I followed a helpful tutorial on implementing middleware pipelines. The tutorial can be found at: https://blog.logrocket.com/vue-middleware-pipelines/. This tutorial demonstrated creating middleware to ...

Can you add links or buttons to the page view using Directus v9?

In my Directus 9 project, I have a table dedicated to contacts that includes their emails and a special button leading to an external site. I am wondering if it is possible to make the email address clickable (as a mailto: link) and still display the spec ...

How can I prevent right-clicking with Ctrl+LeftMouseClick in Firefox on MacOS?

I'm looking to implement a shortcut using Ctrl+LeftMouseClick in my React project. It functions perfectly on Chrome on my Mac, but in Firefox the shortcut initiates a right mouse click (event.button = 2). I believe this may be due to MacOS's Rig ...

Top method for establishing a mysql connection in Express version 4

Recently, I installed node-mysql and started running on express 4. Although I'm new to express, I am eager to learn the best practices for handling database connections. In my current setup, I have app.js var mysql = require('mysql'); //se ...

JavaScript file slicing leads to generating an empty blob

I am currently working on a web-based chunked file uploader. The file is opened using the <input type="file" id="fileSelector" /> element, and the following simplified code snippet is used: $('#fileSelector').on('change', functio ...

Nextjs is facing challenges in enhancing LCP specifically for text content

I've been trying to boost my LCP score by optimizing the text on my page, but it seems stuck and I can't figure out why my LCP isn't improving. Take a look at the screenshot: https://i.stack.imgur.com/xfAeL.png The report indicates that &a ...