Skip to content

useInfiniteQuery: changing the key should create a new cache entry #258

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
razbakov opened this issue Apr 12, 2025 · 4 comments
Open

useInfiniteQuery: changing the key should create a new cache entry #258

razbakov opened this issue Apr 12, 2025 · 4 comments
Labels
🐞 bug this isn't working as expected

Comments

@razbakov
Copy link

razbakov commented Apr 12, 2025

Changing the key should create a new cache entry that cumulates new pages.

Modifying the queryParam does reactively set data to the cached value or trigger query() and merge() in case of cache-miss. However, as the pages variable is shared between all merge calls, queried data from all queryParams are mixed.

Here is a small playground to illustrate the issue. Try triggering few loadMore with queryParam = 'a' and switch it to 'b' and load some extra data.

Ideally, the query function would have access to the current cached data (e.g. in the context argument). Thus, the merge function would receive the accumulated pages of the current key.

Originally posted by @VianneyRousset in #178

@razbakov
Copy link
Author

Can there also be an issue with useQuery? Some times newData in this example is undefined.

import { useQuery, type EntryKey } from '@pinia/colada'
import { useIntersectionObserver } from '@vueuse/core'
import { ref, computed, watch, type MaybeRefOrGetter } from 'vue'

export const useInifiniteQuery = ({
  key,
  query,
  loadMoreButton,
  dataKey,
  page,
}: {
  key: MaybeRefOrGetter<EntryKey>
  query: () => Promise<any>
  loadMoreButton: Ref<HTMLElement | null>
  dataKey: string
  page: Ref<number>
}) => {
  const data = ref<any[]>([])

  const { state, asyncStatus } = useQuery({
    key,
    query,
  })

  const hasMore = computed(() => state.value?.data?.hasMore ?? false)

  function loadMore() {
    console.log('loadMore', hasMore.value, page.value)
    if (hasMore.value) {
      page.value++
    }
  }

  watch(
    state,
    (newData) => {
      console.log('newData', newData.data[dataKey])
      if (page.value === 1) {
        data.value = newData.data[dataKey] ?? []
      } else {
        data.value = [...data.value, ...(newData.data[dataKey] ?? [])]
      }
    },
    { immediate: true }
  )

  useIntersectionObserver(loadMoreButton, ([entry]) => {
    if (
      entry?.isIntersecting &&
      hasMore.value &&
      asyncStatus.value !== 'loading'
    ) {
      loadMore()
    }
  })

  return {
    state,
    data,
    hasMore,
    loadMore,
    asyncStatus,
  }
}

@posva posva added the 🐞 bug this isn't working as expected label Apr 14, 2025
@r-moret
Copy link

r-moret commented May 7, 2025

Hi! I'm having the same stated problem, which sadly makes this feature unusable for me at this moment, do we know anything about any advancement on it?

Is the plan to first resolve the API for useInfiniteQuery()(#178) and then handle this bug, or will this bug be solved independently of the new API?

PS: Thank you so much for all your work @posva!

@VianneyRousset
Copy link

VianneyRousset commented May 7, 2025

@r-moret, I made a quick patch you can use. Froze the pinia-colada version to 0.15.1 in your package.json and use patch-package to apply the following patch after installation.

https://gist.github.com/VianneyRousset/f11fa3afeedf894a0d97a9f3d543651f

@posva
Copy link
Owner

posva commented May 7, 2025

@r-moret It just needs to be fixed (#178 (comment)). I still haven't had the time for it so feel free to give it a try!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐞 bug this isn't working as expected
Projects
Status: 🆕 Triaging
Development

No branches or pull requests

4 participants