1

I would like to use multiple filters on my project.

I use 3 filters : price range , type , uploaded date.

Uploaded_date : is a checkbox , with three fields : Today, Last 2 days , Last 7 days, Any.

Type : is a checkbox, that has three checkbox : type A, Type B, Type C.

Price range : is a number range between 20 and 100.

My three filters should work in the same time with Agular (change) Method. if i update my first filter , and update next filter , filters should be applied on results of the first filter and like that for the rest .

my stackblitz

Is there a way to make all my filters work together. for every filter i change . the next one should apply on the previous one and like that for the rest.

2

2 Answers 2

1

Instead of using multiple if conditions I suggest to you to update your code as follow (StackBlitz).

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

Keep in sync your filters with the power of arrays and spread operator:

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 use the power of getters and array filter to keep in sync 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;
  }

all the best

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

Comments

1

You might consider using rxjs Observables and pipes for data and filtering which is the normal reactive way to go in Angular . https://stackblitz.com/edit/angular-vwtnmt?embed=1&file=src/app/app.component.html

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

HTML:

<table class="table">
    <thead>
        <tr>
            <th scope="col">#</th>
            <th scope="col">titre</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.titre }}</td>
            <td>{{data.price_range }}</td>
            <td>{{data.date | date: 'medium'}}</td>
            <td>{{data.type}}</td>
        </tr>
    </tbody>
</table>

3 Comments

Working with pipes in my case is better. Thanks Man !
@Could you please update the stack link ?
@Taieb Sorry, I couldn't find it. :(

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.