Primeng: Clear filter on table calls multiple times onLazyLoad

Created on 8 Mar 2021  路  6Comments  路  Source: primefaces/primeng

[x] bug report
[ ] feature request
[ ] support request

Current behavior
Calling table.clear() calls multiple times the onLazyLoad event (1 per column + 1 time more)

Expected behavior
Calling table.clear() must clear the applied filters/order and call onLazyLoad 1 time

Minimal reproduction of the problem with instructions
Use a p-table with [lazy]="true". Declare a button wich click event call the clear method of the table.

What is the motivation / use case for changing the behavior?
Once the filter is cleared, the request must by fired only once to prevent performance issues

  • Angular version: 11.0.5

  • PrimeNG version: 11.2.3

  • Browser: [Chrome 89]

pending-review

Most helpful comment

with primeng: ^11.3.1, i also confirm the bug. previously i was using 11.2.1, and this bug didn't exists.

Calling table.reset() has also the same problem.

All 6 comments

with primeng: ^11.3.1, i also confirm the bug. previously i was using 11.2.1, and this bug didn't exists.

Calling table.reset() has also the same problem.

Ran into this issue as well with 11.3.2.

Any news on this, just confirmed that the bug is still there in 11.4.2

Workaround can done using rxjs stream:

  1. Define a new stream property (and subscriptions to keep track of the subscribe):
    ```
    lazyLoadStream = new Subject();
    subscriptions = new Subscription()l
2. In the `ngOnInit` subscribe to that stream. (I'm using `lodash` here for equality check.)
 ```  
ngOnInit() {
  this.subscriptions.add(
      this.lazyLoadStream
        .pipe(distinctUntilChanged(_.isEqual))
        .subscribe(event => this.load(event)),
    );
}
  1. In the onLazyLoad put a clone (I'm using lodash) of the event on the stream. A clone is needed for the distinctUntilChanged:
  onLazyLoad(event: LazyLoadEvent) {
    this.lazyLoadStream.next(_.cloneDeep(event));
  }
  1. Do the actual loading of the data in the load method.
  2. Don't forget to unsubscribe:
ngOnDestroy() {
    this.subscriptions.unsubscribe();
  }

I'm attaching StackBlitz (based on your showcase) of this issue (lazy & table reset programically).

app.component.html

<p-button label="Reset table" (click)="resetTable()"></p-button>
<hr/>
<p-table
    #customerTableRef 
    [value]="customers"
    [lazy]="true"
    (onLazyLoad)="loadCustomers($event)" 
    [paginator]="true"
    [rows]="10"
    [totalRecords]="totalRecords"
    [loading]="loading"
    sortMode="multiple">
    <ng-template pTemplate="header">
        <!--
        <tr>
            <th pSortableColumn="name">Name <p-sortIcon field="name"></p-sortIcon></th>
            <th pSortableColumn="country.name">Country <p-sortIcon field="country.name"></p-sortIcon></th>
            <th pSortableColumn="company">Company <p-sortIcon field="company"></p-sortIcon></th>
        </tr>
        -->
        <tr>
            <th>Name</th>
            <th>Country</th>
            <th>Company</th>
        </tr>        
        <tr>
            <th>
                <p-columnFilter type="text" field="name"></p-columnFilter>
            </th>

            <th>
                <p-columnFilter type="text" field="country.name"></p-columnFilter>
            </th>
            <th>
                <p-columnFilter type="text" field="company"></p-columnFilter>
            </th>
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-customer>
        <tr>
            <td>{{customer.name}}</td>
            <td>{{customer.country.name}}</td>
            <td>{{customer.company}}</td>
        </tr>
    </ng-template>
</p-table>

app.component.ts

import {Component, ViewChild} from '@angular/core';
import { CustomerService } from './customerservice';
import { Customer } from './customer';
import { FilterUtils } from 'primeng/utils';
import { LazyLoadEvent } from 'primeng/api';
import { PrimeNGConfig } from 'primeng/api';
import {Table} from 'primeng/table';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent { 
    datasource: Customer[];

    customers: Customer[];

    totalRecords: number;

    cols: any[];

    loading: boolean;

    @ViewChild('customerTableRef') customerTableRef: Table | undefined;

    constructor(private customerService: CustomerService, private primengConfig: PrimeNGConfig) { }

    ngOnInit() {
        //datasource imitation
        this.customerService.getCustomersLarge().then(data => {
            this.datasource = data;
            this.totalRecords = data.length;
        });

        this.loading = true;
        this.primengConfig.ripple = true;
    }

    loadCustomers(event: LazyLoadEvent) {
        console.log('onLazyLoad : loadCustomers');
        this.loading = true;

        //in a real application, make a remote request to load data using state metadata from event
        //imitate db connection over a network
        setTimeout(() => {
            if (this.datasource) {
                this.customers = this.datasource.slice(event.first, (event.first + event.rows));
                this.loading = false;
            }
        }, 1000);
    }

    resetTable(): void {
      console.log('resetTable');
      this.customerTableRef?.reset();
    }
}

Once I click on the button which triggers this.customerTableRef?.reset();:

resetTable
onLazyLoad : loadCustomers
onLazyLoad : loadCustomers
onLazyLoad : loadCustomers
onLazyLoad : loadCustomers

So I just tied to update to Primeng 12 and this issue still exists. Why has this not been addressed yet as it is a big bug and makes lazy loading with filters completely useless.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Helayxa picture Helayxa  路  3Comments

miresk picture miresk  路  3Comments

papiroca-tm picture papiroca-tm  路  3Comments

markgoho picture markgoho  路  3Comments

jisqaqov picture jisqaqov  路  3Comments