Primeng: p-table : infinite loop sortFunction with http service

Created on 16 Feb 2018  路  16Comments  路  Source: primefaces/primeng

I'm submitting a ... (check one with "x")
```
[ ] bug report => Search github for a similar issue or PR before submitting
[X ] feature request => Please check if request is not on the roadmap already https://github.com/primefaces/primeng/wiki/Roadmap
[ ] support request => Please do not submit support request here, instead see http://forum.primefaces.org/viewforum.php?f=35

Current behavior
The sortFunction with an http call trigger an infinite loop:
The sortFunction event is triggered in p-table construction.
My custom sort function call an http request that return a new array of data with a new reference.
That reference change trigger the rebuild of the p-table, that recall sortFunction.. the loop is created.

Expected behavior
An option to just trigger the sortFunction event on sort icon click

What is the motivation / use case for changing the behavior?
My sort is a back-end sort.

  • Angular version: 5.2.4

  • PrimeNG version: 5.2.0

  • Browser: [all]

Most helpful comment

This can be solved by setting the table to lazy.

HTML:

<p-table [lazy]="true" sortMode="multiple" [value]="yourValues" (onLazyLoad)="sortFunction($event)"> 
        <!--Templates, etc-->
</p-table>

JavaScript:

import { LazyLoadEvent } from 'primeng/api';

sortFunction($event: LazyLoadEvent) {
    //call your http service here. Read the $event.multiSortMeta or $event.sortField to create your query
}

All 16 comments

This can be solved by setting the table to lazy.

HTML:

<p-table [lazy]="true" sortMode="multiple" [value]="yourValues" (onLazyLoad)="sortFunction($event)"> 
        <!--Templates, etc-->
</p-table>

JavaScript:

import { LazyLoadEvent } from 'primeng/api';

sortFunction($event: LazyLoadEvent) {
    //call your http service here. Read the $event.multiSortMeta or $event.sortField to create your query
}

Thanks a lot it works.
An other problem is all columns are sortable, we cannot choose which column are sortable like the dataTable. I think an issue is already open about it.

I think the pSortableColumn directive can be used to do this. Here is an example where each column is rendered manually:

<p-table [lazy]="true" dataKey="id" sortMode="multiple" [value]="values (onLazyLoad)="sort($event)">
        <ng-template pTemplate="header">
            <tr>
                <th pSortableColumn="entryDate"><!--This can be sorted-->
                    Entry Date
                  <p-sortIcon field="entryDate"></p-sortIcon>
                </th>
                <th><!--This can not be sorted-->
                    Some Other Column
                </th>
        </ng-template>
        <!--The rest of the table is ommitted-->
</p-table>

Thanks you very much it works fine. I use a loop to build the template so I put a ternary on the pSortableColumn.
But for me I don't think that's the optimal solution because we don't use the onSort function that is planned for the sorting. I hope PrimeNG will find a fix to use the onSort function.
https://github.com/primefaces/primeng/issues/5164 this issue should fix it

@cagataycivici Can this be closed?

There is pSortableColumnDisabled property to dusable sorting in dynamic colums.

Same issue occurred in p-dataTable how to solve this?

I am getting the same issue.

On sorting, I am calling API. It goes in infinite loop.

This solution given here is not working.

@kaushikparmar just try @noamichael's answer and add [lazy]="true"

Thanks @bakasmarius ,

I am on the way.

Now, I am getting following issues.

  • Not able to decide the scroll position from LazyLoadEvent. On up scroll and down scroll, I am getting the same event object.
  • when I click on column header for sorting, onLazyLoad event also executed with onSort event.

In my case, I have to make http call when scroll ends, to fetch next page data from API.
And On sorting only sort event should be fired not scroll event.
Right now, both events are being executed simultaneously.

    <p-table [value]="row" [scrollable]="true" [scrollHeight]="curentTableHeight" rows="15" [virtualScroll]="true"  [lazy]="true" (onLazyLoad)="loadDataOnScroll($event)" [totalRecords]="totalRecords" [virtualRowHeight]="20" [loading]="isVertualScrollLoading" sortField="merchandise_id" sortMode="single" (onSort)="sortData($event)">

I remember I had the same issue. Try removing (onSort). Here's an example of my table that works with lazy loading + sorting:
` [lazy]="true" [virtualScroll]="true" (onLazyLoad)="displayResults($event);"
[columns]="tableColumns" [value]="items"
[resizableColumns]="true" [reorderableColumns]="true" scrollHeight="740px"
[scrollable]="true" [rows]="lazyLoadIncrement" [virtualRowHeight]="1" [totalRecords]="itemsToLoad"
[loading]="loading"

`

displayResults() includes sorting logic + fetching the data from http.
I hope this helps.

I have query,
i need to call function on page change and on Sorting , separately,
when i use sortFunction then it is calling infite calls,
please let me know, if there is any solution.

`@sagar-kiwi
Following is my code which may help you solve your problem.

I created custom events/directive (appScroll & appFillHeight ) and added it to p-table to extend its functionalities as per my requirements.

app-sort-icon is a custom directive for customised sorting functionality. I can provide you the code for the same if you want.














Category ID





Display/Category Name





Arabic Name





Sequence




Action





{{row?.accessory_cat_id}}






-
{{row?.sequence}}

















No records found



`

Hi there, I am using primeng p-table and have the same infinite loop issue in lazyloading as the columns also get repopulated and that triggers lazyloading continuously. @kaushikparmar How did you solve this issue? Are you able to share the app-sort-icon implementation idea? Thanks!

Why this issue is closed? Is there any workarounds for this issue?

@tibinthomas

This entire thread is the fix. Depends on your scenario though as to the exact combination of settings to use. I found this issue just now because of the same inifinite loop. I didn't want to use the (onLazyLoad) though because all sorting / paging / filtering for us is done in an API.

So I just set [lazy]=true. Problem solved. You don't have to use the onLazyLoad event if, like me, you are populating the table from an observable that retrieves from http.

For additional context, In my scenario, we have separate components for filtering and it's all event driven. So we have Three behavior subjects. One for FilterOptions, one for PagingOptions, and one for SortOptions.

I then have a data$ = combineLatest([this._filterOptions, this._pagingOptions, this._sortOptions]).pipe(etc)

We're using [lazy]="true", with (onSort)=onSort($event) which fires the method and in that method we push new values in to the behavior subject. This in turn triggers the combineLatest operator thus updating the main data$ observable, thus updating the table contents.

Was this page helpful?
0 / 5 - 0 ratings