0

I want to build a filter for a list. The Array of Objects for that looks like this:

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 selects on 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>

and displaying the list 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>

So i am struggling with the filter for the multiple selects, the properties and type array. I want to filter the myList. The filterSet() function is empty at the moment.

1 Answer 1

1

First take a backup ( using lodash cloneDeep) of the original values, without any filters, then when the filters are applied, filter the backup array apply it to the array displayed on the HTML.

  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)
      );
    });
  }

Thanks for providing stackblitz, PFB working example. Issue was that dropdown data names, should match the data in the grid!

stackblitz

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.