Implementing Angular's Advanced Filtering Across Multiple Data Fields

I am looking to create a custom filter for a list. Here is an example of the Array of Objects:

myList: [
  {
    "id": 1,
    "title":"title",
    "city":"city name",
    "types":[
      {
        "id":1,
        "name":"type 1 name"
      },
      {
        "id":2,
        "name":"type 2 name"
      }
    ],
    "properties": [
      {
        "id": 1,
        "name": "prop 1 name"
      },
      {
        "id": 2,
        "name": "prop 2 name"
      }
    ]
  },
  {
    "id": 2,
    "title":"title2",
    "city"":"city name",
    "types":[
      {
        "id":1,
        "name":"type 1 name"
      }
    ],
    "properties": [
      {
        "id": 2,
        "name": "prop 2 name"
      },
      {
        "id": 3,
        "name": "prop 3 name"
      }
    ]
  },
]

I have select fields with multiple options for city, type, and property.

  <form *ngIf="filterForm" [formGroup]="filterForm">
      <div class="row justify-content-start">
        <div class="col-xl-3">
          <mat-form-field appearance="outline">
            <mat-label>Filter by city</mat-label>
            <mat-select formControlName="filterCity" multiple="true">
              <mat-option *ngFor="let city of cities" [value]="city.name">{{city.name}}</mat-option>
            </mat-select>
          </mat-form-field>
        </div>
        <div class="col-xl-3">
          <mat-form-field appearance="outline">
            <mat-label>Filter by type</mat-label>
            <mat-select  formControlName="filterAdType" multiple="true">
              <mat-option *ngFor="let type of Types" [value]="type.name">{{type.name}}</mat-option>
            </mat-select>
          </mat-form-field>
        </div>
        <div class="col-xl-3">
          <mat-form-field appearance="outline">
            <mat-label>Filter by property</mat-label>
            <mat-select  formControlName="filterProperty" multiple="true">
              <mat-option *ngFor="let prop of Properties" [value]="prop.name">{{prop.name}}</mat-option>
            </mat-select>
          </mat-form-field>
        </div>
      </div>
      <div class="row">
        <div class="col-xl-6 text-end">
          <button mat-button color="primary" (click)='filterSet()'>set filters</button>
        </div>
        <div class="col-xl-6 text-start">
          <button mat-button color="primary" (click)='clearFilters()'>clear filters</button>
        </div>
      </div>
     </form>

The list is displayed in a table

        <table class="table table-hover"  *ngIf="myList.length > 0">
          <thead>
            <tr>
              <!-- <th scope="col">#</th> -->
              <th scope="col">Title</th>
              <th scope="col">Type</th>
              <th scope="col">Property</th>
              <th scope="col">City</th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let item of myList; let i = index">
              <td>
                <div>
                  <strong>{{item.title}}</strong>
                </div>
              </td>
              <td>
                <div *ngFor="let type of item.types">
                  {{type.name}}
                </div>
              </td>
              <td>
                <div *ngFor="let prop of item.property">
                  {{prop.name}}
                </div>
              </td>
              <td>{{item.city}}</td>
            </tr>
          </tbody>
        </table>

I am currently facing challenges with filtering the multiple selects, especially the properties and type arrays. The filterSet() function is currently empty.

Answer №1

To begin, it is essential to create a duplicate of the original data values using lodash cloneDeep before implementing any filters. Once the filters have been applied, use this duplicated array to filter the data displayed on the HTML page.

  filterSet() {
    this.pageList = [];
    this.pageList = this.data.filter((x: any) => {
      const { filterCity, filterAdType, filterProperty } =
        this.filterForm.value;
      return (
        (filterCity && filterCity.length
          ? filterCity.includes(x.city)
          : true) &&
        (filterAdType && filterAdType.length
          ? filterAdType.includes(x.types.name)
          : true) &&
        (filterProperty && filterProperty.length
          ? x.properties.find((item) => filterProperty.includes(item.name))
          : true)
      );
    });
  }

Thank you for sharing the stackblitz link. The issue was related to ensuring that the dropdown data names match the data in the grid!

Visit stackblitz for a working example.

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

When trying to use ngModel with Angular, an error occurs where the property 'selected' cannot be created on a string

I'm currently attempting to utilize [(ngModel)] in the following manner: <div class="items"> <tbody> <tr *ngFor="let info of this.information"> <td> <input type="checkbox" [(ngModel)]="this.info.n ...

Troubleshooting the issue of "_this is undefined" in Angular 4

connect=()=>{ this.api=new trovaSDK_Init("normal",this.businessKey,"user","<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="364345534476515b575f5f1e19565d">[email protected]</a>","","","",this.apiCallBack,thi ...

Spring Boot - The Ultimate Guide to Hosting Angular2 Compiled Files

Currently, I am using a Spring Boot restful server alongside an Angular2 front-end application. In an attempt to streamline the process, I have been trying to host the front-end files on Tomcat in order to avoid serving them separately. Unfortunately, desp ...

Using Google Fonts in a Typescript React application with JSS: A step-by-step guide

How can I add Google fonts to my JSS for use in styling? const styles = ({palette, typography}: Theme) => createStyles({ time: { flexBasis: '10%', flexShrink: 0, fontSize: typography.pxToRem(20) }, guestname: ...

What is the process for integrating additional Firebase Cloud Functions into an Angular Universal project?

When working on an Angular Universal project, the fixed configuration for firebase.json looks like this: { "hosting": [{ "target": "PROJECT-ID", "public": "dist/PROJECT-ID/dist/PROJECT-ID/bro ...

Storage in Ionic and variable management

Hello, I'm struggling to assign the returned value from a promise to an external variable. Despite several attempts, I have not been successful. export class TestPage { test:any; constructor(private storage: Storage) { storage.get('t ...

`Angular 6 data table server-side AJAX call issue persists`

Currently utilizing angular datatable version 1.10.19. You can check this out for the server-side Angular approach I have developed a web API in C# to fetch data in the desired format. The server side functionality is working smoothly with the following d ...

Instructions for transferring an Angular / Node.js application to a different computer

Hey there! I'm in the process of transferring my project to a new computer. Just to let you know, I've already set up node.js and mongoDB on the new machine. When it comes to the Angular app, I understand that I need to copy over the frontEnd d ...

Issue with TagCloud functionality when deployed on Vercel platform

Everything functions perfectly on my local machine, but once deployed to Vercel, the display disappears. I've double-checked the text, container, and TagCloud - all showing the correct responses. I even tried uninstalling and reinstalling TagCloud wit ...

How can we best store the component's state in the URL in AngularJS?

I am working with a reusable widget that has its own state. This state includes the content of the search bar (2), one or more select boxes (1), and the tree where the user can pick the currently active element (3). My goal is to create a locationManager ...

There is an issue with types in React when using TypeScript: The type '(user: User) => Element' cannot be assigned to the type '((props: User) => any) & ReactNode'

I'm encountering an error in the terminal and need some assistance. I am not well-versed in TypeScript, so any guidance to resolve this issue would be highly appreciated. https://i.stack.imgur.com/PWATV.png The Loadable component code: import { Circ ...

A method to eliminate the mouse-over effect following the selection of an input box

Currently, I am utilizing Angular and encountering three specific requirements. Initially, there is an input box where I aim to display a placeholder upon pageload as 'TEXT1'. This placeholder should then toggle on mouse hover to display 'TE ...

I'm having trouble understanding why I keep encountering this error message: "SyntaxError: Unexpected token T in JSON at position 0 at JSON.parse (<anonymous>) at XMLHtt…"

I am in the process of implementing a download button feature that will allow users to download a document from my node.js server. Check out this stylish button: https://i.stack.imgur.com/s4CjS.png For the front-end, I am utilizing Angular as the fram ...

NGRX Angular does not support iteration of state.data

I'm attempting to combine state.data with payload.data but encountering an error: TypeError: state.data is not iterable This is my code snippet: on(apiActionGroup.success, (state, payload) => newState(state, { data: { [payload.page?.toStrin ...

Tips for retrieving Angular routing data from external sources outside of an Angular application

Is there a way to automatically generate a sitemap for each module during build time? The project structure is as follows: - cli - client -- Module A -- Routing A -- Module B -- Routing B -- Module C -- Routing C - server I am ...

Incorporate TypeScript with Angular 2 to construct a dictionary with <key, value> pairs. Then, utilize a JSON file to populate the dictionary with data

I am in need of assistance with creating a dictionary or list with a specific structure. I have prepared a json file within my angular 2 project, and I would like to load this data into the dictionary that I am creating. Sample content from my Json file: ...

Mismatch between generic types

When working with this code, I encounter a syntax error at m1 and m2. The error message states: Type 'T' is not assignable to Type 'boolean' or Type 'T' is not assignable to Type 'string' interface customMethod { ...

Ways to avoid route change triggered by an asynchronous function

Within my Next.js application, I have a function for uploading files that includes the then and catch functions. export const uploadDocument = async (url: UploadURLs, file: File) => { const formData = new FormData(); formData.append("file" ...

Tips for displaying and hiding content in Angular2

I have a component that toggles the visibility of elements by clicking a button. This is the snippet of my HTML code: <div *ngFor="let history of histories | sortdate: '-dateModified'"> <p><b>{{ history.remarks }}</b& ...

A guide on cycling through keys in an object with changing values using Typescript

Struggling with a beginner question here - I'm having trouble iterating through an object with dynamic keys in Typescript //This is how I've typed my object let obj: { [key: string]: string } = {}; Using forEach or map isn't working and thr ...