Search code examples
angularprimengprimeng-datatable

PrimeNG Datatable filter value changes to undefined after search with lazy-load


I have a data table that I would like to lazy load and use the built in filters to generate the filters for data api request. Whenever I type something in the filter field it returns the search then changes whatever I typed to "undefined". It still returns the correct array of data so the search is working but the value doesn't stay there afterwards. Here is the code:

Data table template

<p-dataTable [rows]="10" [lazy]="true" [paginator]="true" [pageLinks]="5" [rowsPerPageOptions]="[5,10,20]" [value]="businesses"
  responsive="true" sortable="true" rowExpandMode="single" (onRowCollapse)="deselectContact()"
   [totalRecords]="totalRecords" (onLazyLoad)="loadLazy($event)" expandableRows="true" (onRowExpand)="getDocsContacts($event)">

  <p-column expander="true" [style]="{'width':'30px'}"></p-column>
  <p-column sortable="true" filterMatchMode="equals" [filter]="true" filterPlaceholder="Search" field="tag" header="ID"></p-column>
  <p-column sortable="true" filterMatchMode="equals" [filter]="true" filterPlaceholder="Search" field="name" header="Name"></p-column>
  <p-column sortable="true" filterMatchMode="equals" [filter]="true" filterPlaceholder="Search" field="address1" header="Street"></p-column>
  <p-column sortable="true" filterMatchMode="equals" [filter]="true" filterPlaceholder="Search" field="city" header="City"></p-column>
  <p-column sortable="true" filterMatchMode="equals" [filter]="true" filterPlaceholder="Search" field="state" header="State"></p-column>
  <p-column sortable="true" filterMatchMode="equals" [filter]="true" filterPlaceholder="Search" field="zip" header="Zip"></p-column>
  <p-column  header="Edit" >
    <ng-template pTemplate="body">
      <button>EDIT</button>
    </ng-template>
  </p-column>

  <ng-template let-business pTemplate="rowexpansion">
    <div class="notes">
      <label>Note </label>
      <br/>
      <textarea class="notefield" readonly>{{business.note}}</textarea>

    </div>
    <div class="documents">
      <div class="docs" *ngFor="let currentDoc of currentDocs; let ind = index">
        {{currentDoc.name}}<button>VIEW</button><button>DOWNLOAD</button>
      </div>
    </div>
    <div class="contacts">
      <select (change)="selectContact($event.target.value)">
        <option disabled >Select Contact</option>
    <option *ngFor="let currentContact of currentContacts; let i = index" [value]="i">
      {{currentContact.department}}
    </option>
    </select>
      <div *ngFor="let currentC of currentContacts; let ndx = index">
        <div *ngIf="selectedContact == ndx">
          {{currentC.name}} <br/> {{currentC.phone}} <br/> {{currentC.email}} <br/> {{currentC.website}} <br/> {{currentC.note}}
        </div>
      </div>

    </div>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/>
    <div class="hours">
     {{hoursDisplay}}
    </div>

  </ng-template>
</p-dataTable>

Lazy load function

  loadLazy(event: LazyLoadEvent) {
    console.log(event);
    var sortAscDesc: string;
    var orderWithDirection;
    if(event.sortOrder === -1){
      sortAscDesc = "DESC";
    }
      else if(event.sortOrder === 1){
        sortAscDesc = "ASC";
      }

      if(event.sortField !== undefined){
      orderWithDirection = event.sortField + " " + sortAscDesc; 
      }else {
        orderWithDirection = "tag" + " " + sortAscDesc; 
      }



    var filter = { skip: event.first,
                   limit: event.rows,
                   where: event.filters,
                   order: orderWithDirection,

                    };

                    console.log(filter)
    this.bizapi.find(filter).subscribe((res: Business[]) => {
      this.totalRecords = res.length;
      this.businesses = res;
    });

}

Primeng Datable filter function

 DataTable.prototype.filter = function (value, field, matchMode) {
        if (!this.isFilterBlank(value)){
           var val = "%"+value+"%";
            this.filters[field] =  value;
            // this.filters[field] = { like: val, "options":"i" };
        }else if (this.filters[field])
             delete this.filters[field];
        this._filter();
    };

I did modify the Data table code slightly but that was only to format it so it would work with my api. The original code looked like this:

 DataTable.prototype.filter = function (value, field, matchMode) {
        if (!this.isFilterBlank(value))
            this.filters[field] = { value: value, matchMode: matchMode };
        else if (this.filters[field])
            delete this.filters[field];
        this._filter();
    };

Solution

  • What I ended up doing to solve this was putting the data table function back to its original form and then the filters worked as expected. This did not fix the problem on the API side so I just had to do some extra parsing and object creation to get the formatting correct.