Skip to content

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

@chanithecat

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!

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