Improving Vue.js (Vuex) Getter Functions

Currently, I am in the process of restructuring two getters within vuex. Within my state, there exists a predefined array of objects like so:

 state: {
    color: 'All colors',
    size: 'All sizes',

    allShoes: [
      {
        productId: 1,
        productno: 1234,
        type: 'sneakers',
        brand: 'Nike',
        model: 'Air Zoom',
        gender: 'Men',
        size: ['39', '40', '41', '42', '43', '44', '45'],
        price: 120,
        color: 'red',
        outerMaterial: 'Textile',
        lining: 'Textile',
        sole: 'Textile',
        casingThickness: 'Thin lining',
        fabric: 'Knitwear',
        colors: ['red', 'blue', 'green'],
        image: require('@/assets/images/nike-air-zoom.jpg'),
      },
      {
        productId: 2,
        productno: 1235,
        type: 'sneakers',
        brand: 'Adidas',
        model: 'Ultra Boost',
        gender: 'Men',
        size: ['41', '42', '43', '44', '45'],
        price: 130,
        color: 'white',
        outerMaterial: 'Textile',
        lining: 'Textile',
        sole: 'Textile',
        casingThickness: 'Thin lining',
        fabric: 'Knitwear',
        colors: ['red', 'blue', 'orange'],
        image: require('@/assets/images/adidas-ultra.jpg'),
      },

For the full application, click here.

The intention is to filter products based on color and size. The current solution involves these two getters:

  getters: {
    getProductById: (state) => (id) => {
      return state.allShoes.find((shoe) => shoe.productId === id);
    },
    getProductsByGender: (state) => (gender) => {
      if (state.color === 'All colors' && state.size === 'All sizes') {
        return state.allShoes.filter((shoe) => shoe.gender === gender);
      } else {
        return state.allShoes.filter((shoe) => {
          return (
            (state.color === 'All colors' ||
              (shoe.color === state.color && shoe.gender === gender)) &&
            (state.size === 'All sizes' || shoe.size.includes(state.size)) &&
            shoe.gender === gender
          );
        });
      }
    },
    getProductsByType: (state) => (type) => {
      if (state.color === 'All colors' && state.size === 'All sizes') {
        return state.allShoes.filter((shoe) => shoe.type === type);
      } else {
        return state.allShoes.filter((shoe) => {
          return (
            (state.color === 'All colors' ||
              (shoe.color === state.color && shoe.type === type)) &&
            (state.size === 'All sizes' || shoe.size.includes(state.size)) &&
            shoe.type === type
          );
        });
      }
    },
  }

It has become apparent that there is duplication in code between getProductsByGender and getProductsByType, leading me to consider consolidating them into one getter. In getProductsByGender, filtering by array method is used where access to shoe.gender is required. Comparatively, getProductsByType demands access to shoe.type. Any suggestions for refactoring these two getters or perhaps utilizing a mixin for cleaner implementation would be greatly appreciated as it seems like I may not be following the DRY principle effectively. Your input is valued.

Answer №1

Your function itself isn't necessarily bad, but there may be a way to simplify it down to just one. It's worth noting that if your page is expected to handle a large number of items, you might want to consider performing this task on the backend using a search engine like elastic or algolia.

products(options) {
  if (state.color === "All colors" && state.size == "All sizes") {
    return state.allShoes.filter((shoe) => shoe[options.category] === options.filter);
  } else {
    return state.allShoes.filter((shoe) => {
      return (
        (state.color === "All colors" ||
          (shoe.color === state.color && shoe[options.category] === options.filter)) &&
        (state.size === "All sizes" || shoe.size.includes(state.size)) &&
        shoe[options.category] === options.filter
      );
    });
  }
}

// Here's an example of how to call the function
const products = this.products({
  category: "gender",
  filter: "Female",
});

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

Connecting AngularJS with select options

I am currently developing a checkout feature that calculates shipping prices based on the selected country. If the user picks United States, it should display US. For any other country selection, it should show Not US While the shipping function correctly ...

Unable to refresh the view from the controller once the promise has been resolved

On my webpage, I want to display a dynamic list of items that updates whenever the page is refreshed. To achieve this, I am using Parse to store and retrieve my items using promises. Here's a simplified example of how it works: When the index.html pa ...

Issues with CSS 3 compliance verification are not being resolved

Hey there, I'm currently working on implementing a multi-step form. However, I've run into an issue with adding CSS 3 validation to the form fields as it doesn't seem to be working correctly. Whenever I try to include CSS 3 validation, it sk ...

Using NodeJS, pull JSON data from a JavaScript file and render it in a route file

I am currently utilizing Nodejs Express to work with a script that generates an array of objects from the Google API. My objective is to integrate this JSON data into my templates. How can I invoke the function within my script file from my route file? Be ...

"Unlock the power of Angular.js: Extracting table row data with the click of a checkbox

Can anyone help me with this? I am trying to retrieve all checked data from a table row using Angular.js. Below is my code: <tr ng-repeat="gl in galleryDatas"> <td><input type="checkbox" name=""> {{$index+1}}</td> <td><img ...

What is the standard error function used for jQuery promises?

Is there a way to establish a default error handling function for a jQuery promise? I am running a series of functions asynchronously, and if any of them encounter an error, I want the error to be reported. Currently, this is how I have to handle it: fun ...

Generate table rows by automatically summing the rows and column data using a loop

I'm currently working on a form that dynamically adds data to columns and rows. While I've successfully generated the column names based on database data and used a loop to add details, adding rows has proved to be quite challenging :) Is ther ...

Implementing a Response to an AJAX POST Request with Servlets

I have a unique situation where I need to validate a username input in a text box. The process involves sending the entered username to a server for checking if it has already been taken by another user. If the username is available, I want to change the b ...

Are the elements in the second array the result of squaring each element in the first array? (CODEWARS)

I am currently working on a 6kyu challenge on codewars and I've encountered a frustrating issue that I can't seem to figure out. The task at hand involves comparing two arrays, a and b, to determine if they have the same elements with the same mu ...

Modify the h1 heading text using JavaScript without affecting any other html elements

My aim is to update the content of the h1 tag without affecting any other inner HTML elements. Below is the code I have used: document.getElementById("wpbody-content").getElementsByClassName("wrap")[0].getElementsByTagName('h1')[0].innerHTML = & ...

"Converting GMT date time to a Unix TimeStamp in GMT with JavaScript: A Step-by-Step

There are a multitude of methods available for converting date time into Unix timestamp. The issue arises when trying to convert the date time of GMT into Unix timestamp as it displays the value of the timestamp based on my local timezone (Asia/Kolkata). ...

VueJS - Iterating over a list within a vue component causes the list to be empty

Having encountered an issue with the answers provided to my question from yesterday, I have decided to create a new query with additional details. To review the original question, please visit: VueJS - using mustache template strings inside href attribute ...

li rel=identifier

Can someone assist with choosing rel="28700" in order to update the text within the <li> tag? <li id="pen_li_8" rel="28700"><span class="linkselectValue">Text to be changed</span></li> I have attempted the obvious method: $ ...

What is the best way to calculate the total of all elements in N arrays and then save it in a separate array?

Challenging Task In my current project, I am dealing with multiple arrays (the number of arrays may vary) that need to be summed index by index and then the computed sums stored in a new array. The goal is to add corresponding indexes from different array ...

Tips for developing a nested array of objects using a JavaScript loop

Can someone help me with looping an AJAX response to create an array in this format? "2023-03-30": {"number": '', "url": ""}, "2023-03-30": {"number": '', "url": &quo ...

Troubleshooting: Issue with displaying PHP data on an AngularJS table using JSON through jQuery AJAX

I've been encountering an issue while trying to display data from a database on my HTML page using Angular and JSON. Despite the browser being able to read the database, it fails to show the data. Can anyone shed some light on why this might be happen ...

The lack of definition for the props value poses an issue in React.js Hooks

I'm currently developing a notepad web application that utilizes React Hooks for managing state variables. In order to fetch data from an API, I am using the axios library. The retrieved data consists of objects with fields such as _id, title, status, ...

Combining the data of an object with an array of objects while ensuring that existing key values are not replaced

How can you transform the following array and object: var array = [{key: [3]}, {key1: [3]}, {key1: [3]}] var object = {key1: [3], key2: [3]}; into this output: {key: [3], key1: [9], key2: [3]} All "key" values represent userIds like "LQVjUacPgK" as sho ...

Ways to retrieve the body in a REQUEST using node.js

I am struggling to get actual data back when I call my function, instead I only receive an empty object {}. const Ocr = (file,req,response) => { const options = { method: "POST", url: "https://api.aiforthai.in.th/ocr& ...

Executing the JavaScript function on a batch of 6 IDs at once (should return every 6 calls?)

I'm curious if there's a function available that can group called data into sets of 6. Here's the expanded version of the code var currentResults; function init() { getProducts(); } function getProducts() { $.ajax({ url:" ...