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

Ways to turn off emojis in froala editor

I successfully integrated the Froala editor and dynamically generated an ID for it based on specific requirements. Everything is working well, but I now need to disable emoticons in this editor. $('#froala'+key).froalaEditor({ imageUploadP ...

Having trouble setting breakpoints in Chrome DevTools for my Vue application

Recently, I've encountered an issue where I am unable to place breakpoints in my Vue components as all the line numbers are greyed out. This problem started after updating Chrome to version 102.0.5005.63 from 86.0.4240.75. Could this be related to usi ...

How can I identify when a form has been edited in order to update the database with those changes only?

Currently, I have a form with over 50 fields. While I've successfully implemented functionality for inserting, selecting, and deleting records, I'm struggling with updating a record. Specifically, if a user only updates one or two fields out of t ...

Is it possible for AngularJS components to alter their enclosing element?

I see Angular components as element directives. Take a component named hero, for example, I can include it in the parent template like so: <hero myparam="something"></hero> What I envision is using the hero element as a container managed by t ...

Solving Mixed Content Issues in JavaScript

I'm attempting to retrieve information from OMDB API, but I'm encountering an issue with mixed content images. OMDB pulls its data from IMDB, which does not allow the use of https images. Therefore, all image sources must be prefixed with http. ...

One array comprises of all elements found in a separate array

After grappling with this problem for a while, I still haven't been able to find a solution. If I have 2 arrays structured like this: array1 = [ { name: 'John', age : 25}, { name: 'Jane', age : 58} ] array2 = [ { name: ...

Engage in a Play app featuring AngularJS frontend navigation

Currently, I am using the Play Framework to develop a REST service and I would like the front end to be built with Angularjs in order to make rest calls. I have configured a route provider as follows: angular.module("getAbscencePlans", ["getAbscencePlans. ...

Using Javascript/React to filter an array by a specific value

{ "team_group": ["Alex Smith", "Jake Brown", "Sarah King"], "group_data": { "Alex Smith": { "status": "member" }, "Jake Brown": { "status": &qu ...

The URL in a request is altered prior to execution

I am encountering an issue with my NodeJS application where it automatically appends my domain to the URL set in my http request. How can I prevent this from happening? I have tried to search for similar problems but have not found any relevant solutions. ...

how to switch page direction seamlessly in vue without triggering a page refresh

I'm looking to update the page direction in Pinia whenever a value changes, and while my code is functioning correctly, it reloads the page which I want to avoid. Take a look at my App.vue <script setup> import { useaCountdownStore } from " ...

Develop a pair of jQuery plugins that are able to communicate with one another

My mind is currently in disarray. I am interested in developing two unique jQuery plugins: A tab plugin A slider plugin. These plugins need to be able to communicate with each other. For example, clicking on a tab should activate the corresponding index ...

tips for showcasing an item in a tooltip within a data table

I am working on dynamically creating a table with data retrieved from an ajax response. My goal is to display the data stored in an object within a tooltip attached to each cell. Currently, I have successfully rendered the table, but it is displaying `[obj ...

The Laravel error should occur within the context of a chat application

Encountering an issue with my code. I am using the following event: https://github.com/musonza/chat/blob/master/src/Messages/MessageWasSent.php In the controller: public function sendMessage(Conversation $conversation, Request $request) { $v = Valida ...

The React Material UI Autocomplete, when combined with React-window, causes the list to re-render at the top

Looking for some assistance with React since I'm new to it. Having trouble with the Material-ui autocomplete component and need help from experienced React developers. The issue I'm facing is that when I choose an option from the autocomplete dr ...

The Vuetify Treeview feature ensures that only child nodes are selectable within the tree structure

Is there a way to make only child elements in a Treeview selectable? I've stumbled upon a clever workaround where I exclude setting selectable on the treeview and instead add checkboxes like this: <v-treeview item-key="id" :items="items" ...

Error: The function used in Object(...) is not defined properly in the useAutocomplete file at line 241

I am currently working on a ReactJS application that utilizes Material UI components without the use of Redux. Everything is functioning properly in my application, except when I attempt to integrate the Material UI autocomplete feature, it encounters iss ...

Guide on transmitting data between NextJS and MongoDB

I'm facing an issue where the data from a form is being sent to MongoDB as undefined using nextJS and MongoDB. NewPlayerPage component: const newPlayerPage = (props) => { console.log('props: ' + props); const handleAddPlayer = a ...

I encountered an issue while trying to use jshint with a simple hello world script, receiving the error message: "line 0, col 0, Bad option: 'script'."

This is a basic introduction to my coding journey. function greet() { return 'Hello world'; } Here is the jshint setup I am using: { "browser": true, "browserify": true, "devel": true, "script" ...

Unable to get i18next functioning in my Node.js Express backend

I'm currently facing difficulties in implementing localization for my nodeJS backend. Within my Angular frontend, I have a language-setting interceptor that successfully sets the language in the request header. You can refer to the image below which ...

How can I store the content of a meta tag in a JavaScript variable?

Similar Question: How can I extract data from a meta tag using JavaScript? I have a meta tag that can be customized with content on a specific page, and I'm looking to retrieve this content as a variable in JavaScript. ...