Sorting data in Javascript can be done efficiently by utilizing the .filter method

Can someone help me identify what I might be doing incorrectly? I have a chained filter under computed that is giving me an error message stating 'product.topic.sort' is not a function.

My intention is to use 'select' to provide sorting options such as ascending, descending, high price, and low price.

The v-model is binding the value to the JavaScript.

In the filters section, I'm attempting to add a filter that sorts based on the 'value'.

If the value is undefined, nothing should happen.
If the value is 'Az', it should sort in ascending order.
If the value is 'Za', it should sort in descending order.
If the value is 'Ph', it should prioritize high prices.
If the value is 'Pl', it should prioritize low prices.

Edit

Within the filteredSearch() { method, there are other filters present:

.filter(product => this.filters.some(filter => product.topic.match(filter))) || 
   this.products
  .filter(p => p.topic.toLowerCase().match(this.search.toLowerCase()))
  .filter(p => p.price <= this.priceFilter)

I need to ensure that all the other filters are compatible with the sort filter.

HTML

<div id="app">
            <h4>Sort</h4>  
                <select v-model="value">
                    <option value="Az">Ascending</option>
                    <option value="Za">Descending</option>
                    <option value="Ph">Price High</option>
                    <option value="Pl">Price Low</option>
                </select>



<div class="block" v-for="product in filteredSearch">
        <h3>{{product.topic}}</h3>
          <p>{{product.price}}</p>
</div>
</div>

JS

var app = new Vue({
            el: '#app',
            data: {
                products: [{
                        "topic": "english",
                        "price": "20"
                    },
                    {
                        "topic": "french",
                        "price": "60"
                    },
                    {
                        "topic": "science",
                        "price": "80"
                    }
                ],
                value: "",
            })



computed: {

filteredSearch() {
return this.products
.filter((product) => {
    if (!this.value)
        return true;
    if (this.value == "Az") {
        return product.topic.sort(function(a, b) {
            a.topic - b.topic
        });
    }
})
}
}
});

Answer №1

Check out this demonstration on how to achieve this task. The key is a helper method called getSorter, which examines the currently selected value bound to your v-model directive (this.value) and provides a sorting function based on that selection when using the sort method. If no value is selected, it will return null.

Within your computed property filteredSearch, you can implement your existing filters as desired and then apply sorting afterwards.

methods: {
    // determine which sorting function to use
    getSorter() { 
      switch (this.value) {
        case 'Za':
          return (a,b) => b.topic > a.topic ? 1 : a.topic == b.topic ? 0 : -1;
        case 'Az':
          return (a,b) => b.topic > a.topic ? -1 : a.topic == b.topic ? 0 : 1;
        case 'Ph':
          return (a,b) => b.price - a.price;
        case 'Pl':
          return (a,b) => a.price - b.price;
        default:
          return null;
      }
    }
  },
  computed: {
    filteredSearch: function() { 
      // apply existing filter conditions
      var filteredProducts = this.products
        .filter((el) => true); // insert your current filter criteria here

      // apply sorting function
      var sortFunction = this.getSorter();
      return sortFunction ? filteredProducts.sort(sortFunction) : filteredProducts;
    }
  }

Answer №2

In my opinion, it is advisable to avoid using filters in the computed property function. Instead, consider implementing sorting like this:

filteredSearch() {
return !this.value ? 
        true 
        : this.value == "Az" ? 
        this.products.sort((a, b) => a.topic > b.topic ? 1 : -1)
        : this.value == "Za" ?
        this.products.sort((a, b) => a.topic < b.topic ? 1 : -1)
        : this.value == "Pl" ? 
        this.products.sort((a, b) => a.price - b.price)
        : this.value == "Ph" ?
        this.products.sort((a, b) => b.price - a.price)
        : null;
}

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

What is the best way to access the Node.js HelloWorld File that I created with a .js extension?

I am currently going through the materials at "NodeBeginner.org". Despite my limited experience with command line, I am struggling to execute my first file. The only success I've had so far is running "console.log('helloworld');" by typing ...

To link circles vertically with a line and fill them with color when clicked, follow these steps:

I am looking to create a design similar to the image below using unordered list items. When a user clicks on a list item, I want the circle to fill with color. I have structured it by creating a div with nested list items and span elements. If a user click ...

What are the best ways to transfer information between functional components in a React application?

When working with React, data exchange between class-based components can be done using states and props in the following way: App.js import Name from './Name'; import React, { Component } from 'react' export class App extends Compo ...

Encountering difficulties in compiling Dynamic HTML with the $compile function

I'm attempting to incorporate dynamic HTML into my code with the following lines: var el = $compile('<a ng-controller=\"tableController\" ng-click=\"open\">...ReadMore</a>')($scope); But I'm encounterin ...

Change the state within the click event handler

One issue I'm facing is dealing with 2 submit buttons in my react form. To differentiate between the two buttons, I need to extract the `id` of the one that was clicked using the `onClick` function. Currently, when trying to set the state with this ` ...

Cannot locate module: Error: Unable to find the path '../containers/Layout' in '/home/yusquen/Projectss/react-shop/src/components'

https://i.stack.imgur.com/U1097.png description of image goes here Issue with module: Error: The file '../containers/Login' could not be found in the 'react-shop/src/components' directory. ...

Stop the removal of the CSS content property

When a user enters and re-enters their password, I have a form that checks the strength of the password and displays text accordingly. However, I noticed that if a user makes a mistake and uses the backspace to re-enter the password, the text from data-tex ...

Extract data from axios and display it in a Vue template

Having trouble displaying a value inside a div tag in my nuxt app. An error message keeps popping up saying "Cannot read property 'free_funds' of undefined. Still getting the hang of Axios and Nuxt. Could it be that Bootstrap requires JQuery to ...

Exploring the differences between date formats and implementing text color changes in Vue.js

Currently, I am attempting to compare dates and apply different text colors based on the result. In my .vue file, I have attempted the following approach: <p class="abc" :class="text-red": date1 > new Date()> ...

Eliminating an element from an object containing nested arrays

Greetings, I am currently working with an object structured like the following: var obj= { _id: string; name: string; loc: [{ locname: string; locId: string; locadd: [{ st: string; zip: str ...

JavaScript- Tabbed Navigation with Lists as the Content

Currently, I am facing a frustrating issue in finding a suitable solution. My website uses tabs that utilize the UL, LI system, similar to most tab systems found in tutorials. The problem arises because the javascript on my site interferes with using the ...

Is it possible to customize the width of text color alongside a progress bar?

My Bootstrap 4 Website contains the following HTML code snippet: <div class="container"> <div class="row"> <div class="col-md-6 mx-auto> <h2>Example heading text</h2> <h6>Example subh ...

I have noticed that when I close the Material-UI dialog, it prevents me from interacting with my

After closing the material-ui dialog box, I seem to be unable to click or touch anything on my page. The useState hook is used here: const [open, setOpen] = useState(false); This function is called when handling the dialog close action: const handleClose ...

Dividing a pair of CSS stylesheets on a single HTML page

Currently, I am working on a HTML page that includes multiple javascripts and css files in the header section. <link href="@Url.Content("~/Content/css/main.css")" rel="stylesheet" type="text/css" /> In order to make the website mobile-friendly, I s ...

What is the purpose of Vue emitting and propagating to the parent component?

As a newcomer to Vue, I encountered an issue with my child component. In the code snippet below, I added a validator using the 'emits' property, expecting that if the validation fails, the parent event handler would not be called. However, to my ...

Comparison between setTimeout for this.state and useState

When working with a class component, the code looks like this: setTimeout(() => console.log(this.state.count), 5000); Whereas when using hooks: const [count, setCount] = useState(0); setTimeout(() => console.log(count), 5000); If the setTimeout fun ...

Learn how to synchronize global packages across multiple computers using npm

After installing several npm global packages on my work computer, I am now looking to synchronize these packages with another device. In a typical project, we utilize a package.json file to keep track of package details, making it easy to install all the ...

What is the best approach to managing this scenario where the document is ready?

Just a quick question. I have several JavaScript functions written in this format: var app={ start:function(){ //do something and call calculate }, //end start calculate:function(){ //do more stuff } //end calculate }; //en ...

Angular Promise not executing in a synchronous manner

In the javascript controller, I have a code snippet that consists of two separate functions. While these functions work individually and asynchronously when triggered from the view, my goal is to execute them synchronously on page load. This is necessary b ...

Using PHP to send variables to an AJAX function via parameters

I've encountered an issue while attempting to pass 4 variables through the parameters of the ajax function. The variables I'm trying to pass include the URL, action, ID, and timeout in milliseconds. Unfortunately, the function is not accepting th ...