Home > database >  How can I filter every time the date changes with Angular?
How can I filter every time the date changes with Angular?

Time:01-12

I want to update the data in the table every time the date changes. I prepared a function like this, but it only filters once. It is necessary to refresh the page to perform a filtering for the second time. I tried to refresh the page with the window.location.reload() function, but this time the data comes before filtering.

This is my input

<div >
    <input (change)="filterByDate()" id="date-range-input"  type="text" mwlFlatpickr  placeholder="Select date" mode="range">
</div>

And this is my function

filterByDate() {
    this.dateRange = document.getElementById('date-range-input') as HTMLInputElement
    let dateRangeString = this.dateRange.value
    let startDateString = dateRangeString.substring(0,10)
    let endDateString = dateRangeString.substring(13,24)
    this.startDateObj = new Date(startDateString);
    this.endDateObj = new Date(endDateString);
    console.log(this.startDateObj, this.endDateObj)
    this.clientResults = this.clientResults.filter(m => new Date(m.createddate) >= this.startDateObj && new Date(m.createddate) <= this.endDateObj)
    this.clientResults.sort((a, b) => new Date(b.createddate).getTime() - new Date(a.createddate).getTime());
    this.resultCount = this.clientResults.length
    this.approvedResults = this.clientResults.filter(item => item.boolresult == true).length
    this.rejectedResults = this.clientResults.filter(item => item.boolresult == false).length
    this.totalResultAmount = this.clientResults.filter(item => item.transactionamount).reduce((sum, current) => sum   current.transactionamount, 0);
    this.dateRange = document.getElementById('date-range-input')?.removeAttribute('value')
}

The main problem here is that the filterByDate() function only works with the first change event. But I want to run this function on every change event. How can I do that?

CodePudding user response:

It looks you are using angularx-flatpickr. mwlFlatpickr has an event flatpickrChange which emits on date change. Try using it.

<input (flatpickrChange)="filterByDate()" id="date-range-input"  type="text" mwlFlatpickr  placeholder="Select date" mode="range">

CodePudding user response:

One issue with your current implementation is that the filterByDate function is modifying the clientResults array in place. This means that after the first time the function runs, the array is changed, and the next time the function runs, it's filtering an already filtered version of the array.

Instead, it's better to store a copy of the original data somewhere and filter that data each time the input changes. That way, the original data remains unchanged, and the filter can be reapplied on every change event.

Here's one way you can achieve this:

1.Create a copy of the original data before the function starts:

const originalData = [...this.clientResults];

2.Replace the clientResults variable with originalData variable inside the function.

3.To refresh the page, use ChangeDetectorRef for that, and mark for check after filtering the data

import { ChangeDetectorRef } from '@angular/core';
...
constructor(private cdr: ChangeDetectorRef) {}
...
filterByDate() {
  const originalData = [...this.clientResults];
  this.dateRange = document.getElementById('date-range-input') as 
  HTMLInputElement;
  let dateRangeString = this.dateRange.value;
  let startDateString = dateRangeString.substring(0,10);
  let endDateString = dateRangeString.substring(13,24);
  this.startDateObj = new Date(startDateString);
  this.endDateObj = new Date(endDateString);
  console.log(this.startDateObj, this.endDateObj);
  this.clientResults = originalData.filter(m => new Date(m.createddate) 
     >= this.startDateObj && new Date(m.createddate) <= this.endDateObj);
this.clientResults.sort((a, b) => new Date(b.createddate).getTime() - new Date(a.createddate).getTime());
this.resultCount = this.clientResults.length;
this.approvedResults = this.clientResults.filter(item => item.boolresult == true).length;
this.rejectedResults = this.clientResults.filter(item => item.boolresult == false).length;
this.totalResultAmount = this.clientResults.filter(item => item.transactionamount).reduce((sum, current) => sum   current.transactionamount, 0);
this.dateRange = document.getElementById('date-range-input')?.removeAttribute('value');
this.cdr.detectChanges();
}
  • Related