T
TanStack2w ago
harsh-harlequin

"on-demand" live query returns empty data on remount.

I’m testing the new query-driven sync. First load works great, but if I navigate away and back, the query returns [] and queryFn isn’t called again. Is this something wrong with my implementation, or a bug with on-demand + navigation? I’m trying to emulate the blog post and have a collection like this:
export const todoCollection = createCollection(
queryCollectionOptions({
queryKey: (opts?: LoadSubsetOptions) => buildQueryKey('todos', opts),
queryFn: async (ctx) => {
const params = parseLoadSubsetOptions(
ctx.meta?.loadSubsetOptions ?? undefined,
)

console.log({ params })

return Promise.resolve([
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Charlie' },
])
},
syncMode: 'on-demand',
queryClient,

getKey: (item) => item.id,
}),
)

function buildQueryKey(base: string, opts?: LoadSubsetOptions) {
return [
base,
opts?.where ?? null,
opts?.orderBy ?? null,
opts?.limit ?? null,
] as const
}
export const todoCollection = createCollection(
queryCollectionOptions({
queryKey: (opts?: LoadSubsetOptions) => buildQueryKey('todos', opts),
queryFn: async (ctx) => {
const params = parseLoadSubsetOptions(
ctx.meta?.loadSubsetOptions ?? undefined,
)

console.log({ params })

return Promise.resolve([
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Charlie' },
])
},
syncMode: 'on-demand',
queryClient,

getKey: (item) => item.id,
}),
)

function buildQueryKey(base: string, opts?: LoadSubsetOptions) {
return [
base,
opts?.where ?? null,
opts?.orderBy ?? null,
opts?.limit ?? null,
] as const
}
In my component, I am using it like this:
function TanStackQueryDemo() {
const { data: dataOnDemand = [] } = useLiveQuery((q) =>
q.from({ todo: todoCollection }).where(({ todo }) => eq(todo.id, 1)),
)

return (
function TanStackQueryDemo() {
const { data: dataOnDemand = [] } = useLiveQuery((q) =>
q.from({ todo: todoCollection }).where(({ todo }) => eq(todo.id, 1)),
)

return (
@tanstack/query-db-collection: 1.0.0, @tanstack/react-db: 0.1.44,
1 Reply
harsh-harlequin
harsh-harlequinOP2w ago
I saw in the WIP large saas example on github its done a little differently, which I have emulated to an extent, and it does work as expected there. The critical part being the "preload" in the loader.
function getTodoByIdLiveQuery(todoId: number) {
return createCollection(
liveQueryCollectionOptions({
query: (q) =>
q
.from({ todo: todoCollection })
.where(({ todo }) => eq(todo.id, todoId)),
}),
)
}

export const Route = createFileRoute('/demo/tanstack-query')({
component: TanStackQueryDemo,
loader: async ({ context: { queryClient } }) => {
await Promise.all([
getTodoByIdLiveQuery(1).preload(),
])
return null
},
})

function TanStackQueryDemo() {
const { data: dataOnDemand = [] } = useLiveQuery(
() => getTodoByIdLiveQuery(1),
)

return (
function getTodoByIdLiveQuery(todoId: number) {
return createCollection(
liveQueryCollectionOptions({
query: (q) =>
q
.from({ todo: todoCollection })
.where(({ todo }) => eq(todo.id, todoId)),
}),
)
}

export const Route = createFileRoute('/demo/tanstack-query')({
component: TanStackQueryDemo,
loader: async ({ context: { queryClient } }) => {
await Promise.all([
getTodoByIdLiveQuery(1).preload(),
])
return null
},
})

function TanStackQueryDemo() {
const { data: dataOnDemand = [] } = useLiveQuery(
() => getTodoByIdLiveQuery(1),
)

return (
With this liveQueryCollectionOptions pattern + preload, navigation away and back keeps working as expected. Is the first pattern supposed to work with on-demand, or is there something I’m missing about how queryCollectionOptions handles back-nav / unsubscribe?

Did you find this page helpful?