Sashki Sashka
Sashki Sashka

Reputation: 11

PrimeVue DataTable virtual scroll fires onLazyLoad without scroll

I'm trying to setup infinite scroll for Datatable but have an issue. My fetches triggers without scroll event, one by one. My component is wrapped by .

On this example I add only one Column for better perfomanse. Does anybody can see the problem here? I think I have tryed everything, but no result.

All possible data API fetches fires without scrolling, just on page load. enter image description here

The documentation

const isLoading = ref(true)
const hasMoreData = ref(true)
const showError = ref(false)

const companiesStore = useCompaniesStore()
const showCompany = ref(false)
const showEditModal = ref(false)
const company = ref({})
const offset = ref(0)
const itemsToShow = 7
const isFetching = ref(false)

await companiesStore.getCompaniesTotal("bwf")
const totalRecords = computed(() => companiesStore.BWFTotal)

const companies = ref([])

const fetchInitialCompanies = async () => {
  console.log("initial")
  try {
    const fetchedCompanies = await companiesStore.fetchCompanies({
      type: "bwf",
      limit: 0,
      offset: itemsToShow,
      name: ""
    })
    companies.value = fetchedCompanies
    offset.value += itemsToShow
  } catch (error) {
    console.error("Error fetching initial companies:", error)
  } finally {
    isLoading.value = false
  }
}

fetchInitialCompanies()

const { height } = useWindowSize()
const heightStore = useHeightStore()
const totalHeightGetter = ref(0)
let scrollHeight = ref(null)
let navBottomHeight

watchEffect(() => {
  if (companies.value) {
    navBottomHeight = document.querySelector(".nav").clientHeight
    heightStore.getNavBottomHeight(navBottomHeight) // getter
    totalHeightGetter.value = heightStore.getTotalHeight // getter
    scrollHeight = height.value - totalHeightGetter.value - 18
    scrollHeight = scrollHeight + "px"
  }
})

const loadMoreCompanies = async () => {
  console.log("load more")

  if (isFetching.value || !hasMoreData.value) return
  isFetching.value = true

  try {
    const newCompanies = await companiesStore.fetchCompanies({
      type: "bwf",
      limit: itemsToShow,
      offset: offset.value,
      name: ""
    })

    if (newCompanies.length > 0) {
      companies.value = [...companies.value, ...newCompanies]
      offset.value += itemsToShow
      isFetching.value = false
    } else {
      hasMoreData.value = false // No more data to load
    }
  } catch (error) {
    console.error("Error loading more companies:", error)
  } finally {
    isFetching.value = false
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.4.2/vue.global.min.js"></script>
<div class="table-wrap overflow-auto">
    <div class="table h-full">
      <DataTable
        v-if="!isLoading"
        :value="companies"
        dataKey="id"
        :scrollHeight="scrollHeight"
        scrollable
        removableSort
        tableStyle="max-width: 100%; height: 100%"
        ref="listEl"
        lazy
        :virtualScrollerOptions="{
          delay: 5000,
          lazy: true,
          onLazyLoad: loadMoreCompanies,
          itemSize: 65
        }"
        :totalRecords="totalRecords"
      >
<Column field="name" header="Company" sortable style="width: 100%">
          <template #sorticon> <i class="icon-expand-up-down-line" /> </template>
          <template #body="slotProps">
            <span>{{ slotProps.data.name }}</span>
          </template>
          <template #loading>
            <Skeleton width="75%" />
          </template>
        </Column>
    </DataTable>

Upvotes: 0

Views: 36

Answers (0)

Related Questions