-
-
Notifications
You must be signed in to change notification settings - Fork 32
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
useInifiniteQuery()
for infinite scrolling
#178
Comments
I’m trying to add support for
Looking forward to your insights! |
I'm still collecting feedback on this method. I'm sure it will change a lot in the near future so I would recommend not to support it yet. Currently the approach is to let the user merge the data, but I realized it might be better to still keep an internal representation of the pages, that's why you see different types. |
Could it be done with a middleware like
Although a specific API for infinite scrolling with helpers like |
@lewebsimple Isn't that exactly what the current |
I meant adding this middleware to Nonetheless, as @unnoq stated, I think the concepts of |
Oh I see what you mean! You could indeed transform the data before returning it in query but it would lack the other methods (as you noted) |
I'm loving the implementation of this so far, but do you think it could be extendable to include query parameters, E.g catBreed, catAge? <script setup lang="ts">
import { useInfiniteQuery } from '@pinia/colada'
import { onWatcherCleanup, useTemplateRef, watch, reactive } from 'vue'
import { mande } from 'mande'
export interface CatFacts {
current_page: number
data: Array<{ fact: string, length: number }>
first_page_url: string
from: number
last_page: number
last_page_url: string
links: Array<{
url: string | null
label: string
active: boolean
}>
next_page_url: string | null
path: string
per_page: number
prev_page_url: string | null
to: number
total: number
}
const factsApi = mande('https://catfact.ninja/facts')
const queryParams = reactive({
catBreed: 'Aegean', // Default value, modify as needed
catAge: 5
limit: 10,
})
const {
state: facts,
loadMore,
asyncStatus,
isDelaying,
} = useInfiniteQuery({
key: ['feed', queryParams],
query: async ({ nextPage }) =>
nextPage != null
? factsApi.get<CatFacts>({ query: { ...queryParams, page: nextPage } })
: null,
initialPage: {
data: new Set<string>(),
nextPage: 1 as number | null,
},
merge(pages, newFacts) {
if (!newFacts) return pages
const data = new Set([...pages.data, ...newFacts.data.map((d) => d.fact)])
return {
data,
nextPage: newFacts.next_page_url ? newFacts.current_page + 1 : null,
}
},
retry: 0,
delay: 0,
})
const loadMoreEl = useTemplateRef('load-more')
watch(loadMoreEl, (el) => {
if (el) {
const observer = new IntersectionObserver(
(entries) => {
if (entries[0]?.isIntersecting) {
loadMore()
}
},
{
rootMargin: '300px',
threshold: [0],
},
)
observer.observe(el)
onWatcherCleanup(() => {
observer.disconnect()
})
}
})
</script>
<template>
<div>
<label>
Cat Breed:
<input v-model="queryParams.catBreed" placeholder="Enter breed" />
</label>
<button :disabled="asyncStatus === 'loading' || isDelaying" @click="loadMore()">
Load more (or scroll down)
</button>
<template v-if="facts?.data">
<p>We have loaded {{ facts.data.data.size }} facts</p>
<details>
<summary>Show raw</summary>
<pre>{{ facts }}</pre>
</details>
<blockquote v-for="fact in facts.data.data">
{{ fact }}
</blockquote>
<p v-if="facts.data.nextPage" ref="load-more">Loading more...</p>
</template>
</div>
</template> I'm working on creating a Nuxt project that is a Job board and this would make searching through all my JobPosting so much easier :) |
@Butch78 doesn't that work already if you pass a function to |
Good point, I like your logic much more! And thanks for everything you do for the Vue ecosystem! |
I'm trying to figure out a flexible API for
useInfiniteQuery()
. Goals are:Currently, I have a very simple version that lacks many features:
useInfiniteQuery()
(click to expand source code)It's lacking:
loadMore()
that works with infinite scrollingBy allowing a low level
merge
function, we can fully control the format of the data and we can end up with just a collection that we iterate on the client. We needinitialPage
to make types inferrable inmerge
since it's both the parameter and return type. Here is full example of it's usage with scroll:You can run this example locally with
pnpm run play
and visiting http://localhost:5173/cat-factsI'm looking for feedback of existing needs in terms of caching and data access to implement a more feature-complete
useInfiniteQuery()
The text was updated successfully, but these errors were encountered: