primevue
primevue copied to clipboard
DataView: Paginator prop watcher timing issue
Describe the bug
The paginator of DataView and DataTable can be controlled by the props totalRecords
, rows
and first
.
In case the data is lazy loaded, sorting, filtering, etc. is done on serverside, these values are updated based on the servers response.
The Paginator component has three watchers to check for changes in any of the three props (https://github.com/primefaces/primevue/blob/master/components/lib/paginator/Paginator.vue#L81:L93)
In case the index of the first entry on the current page (first) is higher than the totalRecords the page is changed to the last possible page. (see https://github.com/primefaces/primevue/blob/master/components/lib/paginator/Paginator.vue#L88:L91)
This makes sense, however in case totalRecords
and first
are updated at the same time, this will also trigger the page change behavoir, even if the new first
value is lower than totalRecords
because the totalRecords-watcher is still using the old first
value.
If you also add @page
to DataView to request content of a different page on manual page change via the paginator, this bug will cause a second request.
Reproducer
https://stackblitz.com/edit/w1mnbh?file=src%2FApp.vue
PrimeVue version
3.51.0
Vue version
3.x
Language
ALL
Build / Runtime
Vite
Browser(s)
No response
Steps to reproduce the behavior
- Go to the last page
- Apply the filter (Button on the top left)
- See 4. page is shown
Expected behavior
- Go to the last page
- Apply the filter (Button on the top left)
- See 1. page is shown (as the request with the filter requests page=1)
How to fix?
A temp. workaround is to add an artificial delay, to first update the first prop and than the totalRecords prop.
ProductService.getProducts(params).then(async (response) => {
products.value = response.data;
// First update the from (first) value
meta.value.from = response.meta.from;
// Add delay, so the paginator can already change to the correct new page
await nextTick();
// Apply all other paginator changes
meta.value = response.meta;
});