Implementing multiple filters for object arrays in Angular 8

On my current project, I am interested in implementing multiple filters.

The filters I want to use include price range, type, and uploaded date.

For uploaded date, I have a checkbox with options for Today, Last 2 days, Last 7 days, and Any.

When it comes to type, I have checkboxes for Type A, Type B, and Type C.

Price range will be a numeric value ranging from 20 to 100.

It is essential that all three filters work simultaneously using Angular's (change) method. When I update one filter, the subsequent filters should be applied based on the results of the previous filter, and so on.

You can view my project on stackblitz.

I am looking for a solution that allows all my filters to interact cohesively. Each filter change should affect the next filter in line, creating a seamless filtering experience.

Answer №1

If you're tired of using multiple if conditions, I have a suggestion for you to streamline your code. Check out the updated version below (StackBlitz):

vehiculeFilter: any[] = [];
postedWithinFilter: any[] = [];

By keeping your filters in sync using arrays and the spread operator, you can simplify your code:

onChangeUploadedDate($event, duration) {
    const checked = $event.target.checked;
    if(checked) {
      this.postedWithinFilter = [...this.postedWithinFilter, {...duration}];
    } else {
      this.postedWithinFilter = [...this.postedWithinFilter.filter(x => x.id !== duration.id)];
    }
  }

onChangeVehicule($event, vehiculeType) {
    const checked = $event.target.checked;
    if(checked) {
      this.vehiculeFilter = [...this.vehiculeFilter, {...vehiculeType}];
    } else {
      this.vehiculeFilter = [...this.vehiculeFilter.filter(x => x.id !== vehiculeType.id)];
    }
  }

Then, leverage getters and array filters to stay in sync with your UI:

public get filteredData(): any[] {
    let filtered = [...this.datas];

    if(this.postedWithinFilter.length > 0) {
      filtered = filtered.filter(x => {
        const p = this.postedWithinFilter.find(v => {
          const d = new Date();
          d.setDate(d.getDate() - (v.value));
          const tDate = new Date(x.date);
          return tDate >= d;
        });
        return p != null;
      });
    }

    if(this.vehiculeFilter.length > 0 ) {
      filtered = filtered.filter(x => {
        const t = this.vehiculeFilter.find(v => v.name === x.type);
        return t != null;
      });
    }
    return filtered;
  }

Wishing you all the best!

Answer №2

One effective approach in Angular is to leverage rxjs Observables and pipes for handling data and filtering, following the reactive programming paradigm. Check out this example on StackBlitz for reference

  private data$ = new BehaviorSubject<Data[]>([]);
  dataWithFilters$: Observable<Data[]> = this.data$.pipe(
    this.vehicleTypeFilter,
    this.dateOptionsFilter,
    this.priceFilter
  );
  get vehicleTypeFilter() {...}
  get dateOptionsFilter() {...}
  get priceFilter() {...}

For the HTML implementation:

<table class="table">
    <thead>
        <tr>
            <th scope="col">#</th>
            <th scope="col">title</th>
            <th scope="col">price range</th>
            <th scope="col">date</th>
            <th scope="col">type</th>
        </tr>
    </thead>
    <tbody *ngFor="let data of (dataWithFilters$ | async)">
        <tr>
            <th scope="row">{{data.id }}</th>
            <td>{{data.title }}</td>
            <td>{{data.price_range }}</td>
            <td>{{data.date | date: 'medium'}}</td>
            <td>{{data.type}}</td>
        </tr>
    </tbody>
</table>

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

Navigating through different components in React is made possible with React Router

I have views in my application that depend on each other. For example, in one view a user can choose an item from a list (generated on the server), and in the next view they can perform operations on that selected item. The item is passed to the second v ...

Laravel and Vue: tackling pagination issues in a Vue.js and Laravel application

I'm struggling with getting Laravel pagination to function properly. Although I attempt to access results from different pages, I find that I can only retrieve the first page. Even when I click on page 2, upon checking the request payload, it always i ...

Issue with JSViews visible link and converter not functioning properly

After updating to the latest version of JsViews, I encountered a problem. When using a data-link like "visible{:property}", everything works fine. However, when using a data-link like "visible{convert:property}", it does not work as expected. It appears ...

Google maps are failing to display on the page when loading via ajax

When I click a button, I use AJAX to load a page, but the map on the loaded page is not displaying. There are no errors showing up either. I have tried adding initmap() after the ajax load, but it doesn't work. Do I need to bind it somehow? What am I ...

Utilize generics to define the data type of the output

Within my Angular service, there is a method that retrieves data from Sync Storage: getFromSyncStorage(key: string): Promise<Object | LastErrorType> { return new Promise(function (resolve, reject) { chrome.storage.sync.get(key, function ( ...

Insert well-formed JSON into an HTML element

I'm facing a challenge while trying to dynamically embed a valid JSON array into HTML. The issue arises when the text contains special characters like quotes, apostrophes, or others that require escaping. Let me illustrate the problem with an example ...

Consecutive interdependent operations within a Vuex action

I'm currently working on a Vue application that is pulling data from the Contentful API. I have a thumbnail (image) field for each entry and I want to extract the main colors as hexadecimal values and store them in the state for use throughout the app ...

Guide to deploying Angular 17 in server-side rendering mode on Firebase

I've been delving into this issue for the past week, but still haven't found a definitive solution. I created an Angular 17 project in server-side rendering mode, installed Firebase via npm, built the project, used 'firebase init hosting&apo ...

What could be causing the page to refresh every time a post or update is made using a mock REST API with JSON

I have been using Json-Server to mock API requests, but I'm facing an issue where the page reloads every time I fetch or update a post. I've tried searching for a solution, but haven't found one yet. Interestingly, even though I followed a ...

Angular and Ionic collaborate by using ngFor to pass on the item.id during a (click) event

I have a list of items and I want to dynamically change the height of a card when I click on a button that is located on the card. Can anyone guide me on how to achieve this? I attempted to pass the item.id through a click event and use the id in a functi ...

HTTP request form

I'm currently working on a form that utilizes XMLHttpRequest, and I've encountered an issue: Upon form submission, if the response is 0 (string), the message displayed in the #output section is "Something went wrong..." (which is correct); Howe ...

When React object state remains unchanged, the page does not update automatically

i have a state object with checkboxes: const [checkboxarray_final, setCheckboxarray_final] = useState({ 2: ",4,,5,", 9: ",1,", }); i'm working on enabling check/uncheck functionality for multiple checkboxes: these are ...

"How to set the header in AngularJS when opening a new window with a GET request URL

Can anyone provide guidance on setting headers and opening a URL (https://www.example.com) in a new window without including sensitive authentication information in the URL parameters? I am working with AngularJS for this task. I have searched through exi ...

Ways to remove items from Vuex store by utilizing a dynamic path as payload for a mutation

I am looking to implement a mutation in Vuex that dynamically updates the state by specifying a path to the object from which I want to remove an element, along with the key of the element. Triggering the action deleteOption(path, key) { this.$store.d ...

Encountering an issue with the message "chartobject-1.render() Error >> Unable to locate the container DOM element." within a JavaScript function

I have encountered an issue while working with Fusion Charts in my HTML page using JavaScript. When attempting to display two charts simultaneously, I receive an error message that says: "fusioncharts.js:71 Uncaught RuntimeException: #03091456 chartobjec ...

How about this: "Is it possible for the accordion to open when clicked and show

Screenshot illustrating the issue I need assistance with implementing a hover preview for the contents of the accordion, followed by keeping it open upon clicking. The codepen link is provided below for reference: Visit the codepen here <script src=&q ...

Expanding the outer div with Jquery's append() function to accommodate the inner div elements perfectly

I am facing an issue where my outer div does not expand automatically to fit the elements I append inside it using jQuery. The structure of my div is as follows: <div class="well" id='expand'> <div class="container"> < ...

send mouse event to component when clicked

Looking to retrieve mouse coordinates in an Angular component. This is the HTML snippet: <div id="container" class="fullSize" style="height:100%;" (click)="onClick(ev)"></div> And here's the corresponding function in the TypeScript file ...

Typescript: Extracting data from enum items using types

I am facing a challenge with an enum type called Currency. I am unable to modify it because it is automatically generated in a graphql schema. However, I need to utilize it for my data but I'm unsure of how to go about doing so. enum Currency { rub ...

Numerous status buttons with a variety of background colors

There are 3 buttons on the order page: [New Order], [Processing], and [Completed]. When the processing button is clicked, the background of the button should change and the order status will be updated in the database. The [New Order] button will have a ...