Utilizing various filters and sorting options on API response within Angular 8

Upon receiving the following API response:

[
    {
      "imgPaths":[
         "gallery/products/55ccb60cddb4d9bded02accb26827ce4"
      ],
      "_id":"5f3e961d65c6d591ba04f3d3",
      "productName":" Jiva Ayurveda Honey (500g) ",
      "categoryId":{
         "_id":"5f2139322d46a455487b2ea6",
         "categoryName":"Nutrition and supplements",
         "imgPath":"gallery/category/c20ae1717899fad2a6ff3f3ceab381ff"
      },
      "manufacturer":"Jiva",
      "basePrice":"190",
      "finalPrice":"187",
      "availability":"in-stock",
      "createdAt":"2020-08-20T15:26:21.092Z"
   },
   {
      "imgPaths":[
         "gallery/products/72b0e1cf078f26ed0ec0280c1cf8865d"
      ],
      "_id":"5f3e962465c6d591ba04f3d4",
      "productName":"Baidyanath Keshrikalp Royal Chyawanprash (500g) ",
      "categoryId":{
         "_id":"5f2139322d46a455487b2ea6",
         "categoryName":"Nutrition and supplements",
         "imgPath":"gallery/category/c20ae1717899fad2a6ff3f3ceab381ff"
      },
      "manufacturer":"Baidyanath",
      "basePrice":"394",
      "finalPrice":"378",
      "availability":"in-stock",
      "createdAt":"2020-08-20T15:26:28.103Z"
   }
]

I am looking to implement multiple filters for 'manufacturer' and 'finalPrice', as well as various sorting options such as 'high to low', 'low to high', and 'recently added'. To achieve this, I have written the following methods:

  1. To handle sorting:
    onSortChange(event) {
        if(event.value==="Lowtohigh"){
          this.productsbycategory.sort((a, b) => {
                return Number(a.finalPrice) - Number(b.finalPrice); 
           })
          }
          else if(event.value==="hightolow"){
            this.productsbycategory.sort((a, b) => {
              return Number(b.finalPrice) - Number(a.finalPrice);
            })
           }
          else if(event.value==="recentlyadded"){
            this.productsbycategory.sort((a, b) => {
              return +new Date(b.createdAt) - +new Date(a .createdAt);
            })
        }
    }
  1. For filtering by manufacturer:

onBrandFilterChange(event) {

  if(event.target.checked===true && !numbers.includes(event.target.value)){
    numbers.push(event.target.value);
    this.productsbycategory= _.filter(this.filteredProducts, function(p){
      return _.includes(numbers, p.manufacturer);
    });
  }
  else if(event.target.checked===false && numbers.includes(event.target.value)){
    _.pull(numbers,event.target.value);
    if(numbers.length>0){
    this.productsbycategory= _.filter(this.filteredProducts, function(p){
      return _.includes(numbers, p.manufacturer);
    });
    }
    else{
        this.setData();
    }
  }
}
  1. For filtering by price range:
onPriceFilterChange(min, max) {
    console.log(min, max);
    if (min >= 1 && max <= 5000) {
      this.productsbycategory = this.productsbycategory.filter(function (elem) {
        return Number(elem.finalPrice) >= min && Number(elem.finalPrice) <= max;
      });
    } else {
      alert('Please select a valid price range');
    }
  }


I aim to enhance the existing code to enable applying all filters and sorting functionalities simultaneously. }

Answer №1

Make sure to follow this method. Take note of the comments in the code and test it by clicking on the 'Run code snippet' button

// Information you are working with
data = [
    {
      "imgPaths":[
         "gallery/products/55ccb60cddb4d9bded02accb26827ce4"
      ],
      "_id":"5f3e961d65c6d591ba04f3d3",
      "productName":" Jiva Ayurveda Honey (500g) ",
      "categoryId":{
         "_id":"5f2139322d46a455487b2ea6",
         "categoryName":"Nutrition and supplements",
         "imgPath":"gallery/category/c20ae1717899fad2a6ff3f3ceab381ff"
      },
      "manufacturer":"Jiva",
      "basePrice":"190",
      "finalPrice":"187",
      "availability":"in-stock",
      "createdAt":"2020-08-20T15:26:21.092Z"
   },
   {
      "imgPaths":[
         "gallery/products/72b0e1cf078f26ed0ec0280c1cf8865d"
      ],
      "_id":"5f3e962465c6d591ba04f3d4",
      "productName":"Baidyanath Keshrikalp Royal Chyawanprash (500g) ",
      "categoryId":{
         "_id":"5f2139322d46a455487b2ea6",
         "categoryName":"Nutrition and supplements",
         "imgPath":"gallery/category/c20ae1717899fad2a6ff3f3ceab381ff"
      },
      "manufacturer":"Baidyanath",
      "basePrice":"394",
      "finalPrice":"378",
      "availability":"in-stock",
      "createdAt":"2020-08-20T15:26:28.103Z"
   }
];

// Function for filtering by price
// Input data array, minimum and maximum price
const priceFilter = (data, min, max) => data.filter((item) => item.finalPrice >= min && item.finalPrice <= max);

// Function for filtering by manufacturer
// Provide name
const manFilter = (data, man) => data.filter((item) => item.manufacturer.toLowerCase() === man.toLowerCase());

// Sort the data array based on specific parameters
// Provide data array and options object:
// desc:true for descending sort (ascending as default), 
// price:true to sort by price or date:true to sort by date.
const customSort = (data, { desc, price, date }) => data.sort((a, b) => {
  if(desc) { const c = a; a = b; b = c; }
  if(price) return a.finalPrice - b.finalPrice;
  else if(date) return new Date(a.createdAt) - new Date(b.createdAt);
});

// Testing

// Sort in descending order by date
console.log('Sorting test: ', customSort(data, { desc: true, date: true }));

// Filter by price
console.log('Filtering by price test:', priceFilter(data, 200, 400));

// Filter by name (case insensitive)
console.log('Filtering by name test: ', manFilter(data, 'JIVA'));

If you need to apply multiple filters step by step, follow these steps

// data = [ ... Add your data here... ];

// Start by filtering your data by manufacturer
data = manFilter(data, 'Baidyanath');

// Next, take the previously filtered data
// and filter again by price range
data = priceFilter(data, 100, 300);

// Then, take the data filtered by manufacturer and price range
// and perform an ascending sort based on the price field
data = customSort(data, { price: true });

// Your data is now filtered and sorted
// Proceed with your programming logic
return data;

Answer №2

If you need to customize your data filtering:

For the most recently added items:

data.filter(item=>new Date(item.createdAt)).reverse()

To sort from Low to High or High to Low:

data.filter(item=>Number(item.finalPrice)).sort()
data.filter(item=>Number(item.finalPrice)).reverse()

Thank you!

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

Where can Vue.js be found?

After dedicating an hour to watching instructional YouTube videos on Vue.js, I am still struggling to grasp the language! In the past, I have worked with Node.js, Jquery, and Mongodb to develop websites... I believe that web applications require multiple ...

ReactJs Unicode Integration with ID3 JS

I am working on a React Project that involves using an input type = "file" to upload music files. I am able to extract tags using ID3 Js, but the result is displayed in this format: https://i.stack.imgur.com/192co.png Is there a way to convert ...

Merge JSON objects into an array

Is there a way to merge JSON objects when the initial object is: { "total": "2" } And the second one is: [ "player1": { "score": "100", "ping": "50" }, "player2": { "score": "100", "ping": "50" ...

Iterate over each option in a select dropdown menu and modify them

Below is the test code snippet I am working with: ID = { CreatedBy: { id: 'createdBy' }, ModifiedBy: { id: 'modifiedBy' } } Profile = { All: { text: 'All', val: 0 }, Sys: { text: '<a href="/cdn-cgi/l/emai ...

Steps for resetting data() on a route without parameters:

Having trouble restarting a route on a new editor I have a specific route /editor as well as /editor?_id=dasd448846acsca The /editor route consists of a simple form with empty inputs, while the /editor?_id=dasd448846acsca route has the same component bu ...

Utilizing Angular's ngShow and ngHide directives to hide spinner when no data is retrieved

I'm having an issue with the HTML code below. It currently displays a spinner until a list of tags is loaded for an application. However, the spinner continues even if no events exist. I want to make the spinner disappear and show either a blank inpu ...

Fill up the table using JSON information and dynamic columns

Below is a snippet of JSON data: { "languageKeys": [{ "id": 1, "project": null, "key": "GENERIC.WELCOME", "languageStrings": [{ "id": 1, "content": "Welcome", "language": { ...

I'm encountering a 502 error while trying to use Supabase's signInWIthPassword feature

Despite all authentication functions working smoothly in my React, TypeScript, and Supabase setup, I'm facing an issue with signInWithPassword. In my context: I can successfully signIn, create a profile, and perform other operations like getUser() an ...

Ways to thwart CSRF attacks?

I am currently looking for ways to protect my API from CSRF attacks in my Express app using Node.js. Despite searching on both Google and YouTube, I have been unable to find a solution that works for me. One tutorial I watched on YouTube recommended gene ...

How can VueJs effectively update the data fetched using the created function?

When working with the Promise Object, I prefer to utilize the "then" and "catch" functions instead of asynchronous functions for handling responses in a simpler way. This allows me to avoid using await and conditional if-else statements to check the stat ...

Is it necessary to compile Jade templates only once?

I'm new to exploring jade in conjunction with express.js and I'm on a quest to fully understand jade. Here's my query: Express mentions caching jade in production - but how exactly does this process unfold? Given that the output is continge ...

The Angular template loads and renders even before the dynamic data is fetched

I'm encountering a frustrating issue where the page loads before the data is retrieved. When I log the names in $(document).ready(), everything appears correct without any errors in the console. However, the displayed html remains empty and only shows ...

Convert the generic primitive type to a string

Hello, I am trying to create a function that can determine the primitive type of an array. However, I am facing an issue and haven't been able to find a solution that fits my problem. Below is the function I have written: export function isGenericType ...

When switching tabs, Ion-select should not reload the selected name

Whenever I switch tabs and then return to the previous tab in Ionic, the select field that was previously set becomes null, even though the page is still loading and the variable is populated. <ion-header color="primary"> <ion-navbar> &l ...

Which internal API allows for navigating to the daygridmonth, timegridweek, and timegridday views using a custom button?

I am looking to have the dayGridMonth displayed when I click on a custom button within FullCalendar. The functionality I want is for the dayGridMonthFunc to access the internal API daygridmonth and display the screen as a month. <div> & ...

Exploring Mixed Type Arrays Initialization in Typescript using Class-Transformer Library

In my class, I have a property member that is of type array. Each item in the array can be of various types such as MetaViewDatalinked or MetaViewContainer, as shown below class MetaViewContainer{ children: (MetaViewDatalinked | MetaViewContainer)[]; ...

Utilizing vue-property-decorator: Customizing the attributes of @Emit

After seeing the @Emit feature, I checked out the example on GitHub. import { Vue, Component, Emit } from 'vue-property-decorator' @Component export default class YourComponent extends Vue { count = 0 @Emit() addToCount(n ...

Accessing elements within documents opened using the window.open method

My goal is to open a new browser window based on a provided URL using JavaScript's window.open function. However, my ultimate aim is to inspect the newly opened window and alter its URL to redirect to a different site. I attempted to achieve this with ...

What is the best way to target all elements sharing a common class?

Currently, I have a Boolean variable stored in a hidden input field. When the user is signed in, it's set to false; otherwise, it's set to true. I have download buttons that should link to a file for download. My goal is to hide these buttons an ...

Combining Django's CSRF token with AngularJS

I currently have Django running on an Apache server with mod_wsgi, and an AngularJS app being served directly by Apache rather than through Django. My goal is to make POST calls to the Django server that is utilizing rest_framework, but I am encountering d ...