Skip to content

Error [QueryCollection] queryClient must be provided. on Tanstack Start's beforeLoad #436

Description

@chanithecat

Hi all!

Im getting an error when I try to prefetch a live query in Tanstack Start's lifecycle functions like loader and beforeLoad.

An error occured while server rendering /chats/rhelkg6obiily4yrfwky1bsb:

	[QueryCollection] queryClient must be provided.

QueryClientRequiredError: [QueryCollection] queryClient must be provided.
    at queryCollectionOptions (/home/chani/Documents/projects/chat-demo/node_modules/@tanstack/query-db-collection/src/query.ts:462:11)
    at /home/chani/Documents/projects/chat-demo/src/lib/collections/chat.ts:11:31
	...rest of stack trace

Occurs when I run a prefetch on the beforeLoad

import { createLiveQueryCollection, eq } from '@tanstack/react-db'
import { createFileRoute, useLocation } from '@tanstack/react-router'
import { chatCollection } from '@/lib/collections/chat'

const getChat = (chatId: string) => {
  return createLiveQueryCollection({
    query: (q) =>
      q
        .from({ chat: chatCollection })
        .select(({ chat }) => ({ ...chat }))
        .where(({ chat }) => eq(chat.id, chatId)),
  })
}
export const Route = createFileRoute('/_protected/chats/$chatId')({
  ssr: false,
  beforeLoad({ location, params }) {
    const existingChat = location.state.existingChat
    if (existingChat) {
      getChat(params.chatId).preload()
    }
  },
  component: RouteComponent,
  ssr: false,
})

function RouteComponent() {
  const { state } = useLocation()

  return (
    <div>
      <div>Hello "/_protected/chats/$chatId"! </div>
      <pre>{JSON.stringify(state, null, 2)}</pre>
    </div>
  )
}

Its saying that I didnt provide queryClient in chatCollection in chat.ts even though i did.

// chat.ts
import {
  createCollection,
} from '@tanstack/react-db'
import { queryCollectionOptions } from '@tanstack/query-db-collection'
import { createChat, createChatSchema, getChats } from '@/lib/server/chat'
import { queryClient } from '@/lib/queryClient'

export const chatCollection = createCollection(
  queryCollectionOptions({
    queryClient,
    queryKey: ['chats'],
    queryFn: async () => await getChats({ data: { limit: 24 } }),
    schema: createChatSchema,
    startSync: true,
    getKey: (item) => item.id,
    onInsert: async ({ transaction }) => {
      const newChats = transaction.mutations.map((m) => m.modified)

      await Promise.all(
        newChats.map((chat) =>
          createChat({
            data: { user2Id: chat.user2Id! },
          }),
        ),
      )
    },
  }),
)

export const loadMoreChats = async (lastChatDate: Date) => {
  const newChats = await getChats({
    data: { limit: 8, beforeDate: lastChatDate },
  })

  chatCollection.utils.writeBatch(() => {
    newChats.forEach((chat) => {
      chatCollection.utils.writeInsert(chat)
    })
  })
}

Its working fine in a component but not in the loader. Am i doing something wrong? Im trying to make it a route guard though perhaps this is just bad usage?

Thanks in advance!

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions