Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/tanstack/query/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The QueriesObserver allows you to observe multiple queries at once and optionally combine their results. It’s the foundation for framework-specific hooks like useQueries in React.

Constructor

const observer = new QueriesObserver<TCombinedResult>(
  client: QueryClient,
  queries: Array<QueryObserverOptions>,
  options?: QueriesObserverOptions<TCombinedResult>
)
client
QueryClient
required
The QueryClient instance
queries
Array<QueryObserverOptions>
required
Array of query options
options
QueriesObserverOptions<TCombinedResult>
Example:
const observer = new QueriesObserver(queryClient, [
  {
    queryKey: ['todos'],
    queryFn: fetchTodos,
  },
  {
    queryKey: ['users'],
    queryFn: fetchUsers,
  },
])

Methods

subscribe()

Subscribes to updates from all queries.
const unsubscribe = observer.subscribe(
  listener: (results: Array<QueryObserverResult>) => void
): () => void
listener
(results: Array<QueryObserverResult>) => void
required
Callback function that receives an array of query results
Returns: Function to unsubscribe Example:
const unsubscribe = observer.subscribe((results) => {
  const [todosResult, usersResult] = results
  
  console.log('Todos:', todosResult.data)
  console.log('Users:', usersResult.data)
  
  // Check if all queries are loaded
  const allLoaded = results.every(result => result.isSuccess)
  console.log('All loaded:', allLoaded)
})

// Later, unsubscribe
unsubscribe()

getCurrentResult()

Returns the current results from all queries without subscribing.
const results = observer.getCurrentResult(): Array<QueryObserverResult>
Returns: Array of current query results Example:
const results = observer.getCurrentResult()
const isAnyLoading = results.some(result => result.isLoading)
const allSuccess = results.every(result => result.isSuccess)

setQueries()

Updates the queries being observed.
observer.setQueries(
  queries: Array<QueryObserverOptions>,
  options?: QueriesObserverOptions<TCombinedResult>
): void
queries
Array<QueryObserverOptions>
required
New array of query options
options
QueriesObserverOptions<TCombinedResult>
New observer options
Example:
observer.setQueries([
  {
    queryKey: ['todos'],
    queryFn: fetchTodos,
    staleTime: 10000, // Updated option
  },
  {
    queryKey: ['users'],
    queryFn: fetchUsers,
  },
  {
    queryKey: ['posts'], // New query added
    queryFn: fetchPosts,
  },
])

getQueries()

Returns the underlying Query instances.
const queries = observer.getQueries(): Array<Query>
Returns: Array of Query instances

getObservers()

Returns the underlying QueryObserver instances.
const observers = observer.getObservers(): Array<QueryObserver>
Returns: Array of QueryObserver instances

getOptimisticResult()

Returns optimistic results and a combine function.
const [rawResults, combineResults, trackResults] = observer.getOptimisticResult(
  queries: Array<QueryObserverOptions>,
  combine?: (results: Array<QueryObserverResult>) => TCombinedResult
): [
  rawResult: Array<QueryObserverResult>,
  combineResult: (r?: Array<QueryObserverResult>) => TCombinedResult,
  trackResult: () => Array<QueryObserverResult>
]
Returns: Tuple of [rawResults, combineFunction, trackFunction]

destroy()

Destroys the observer and cleans up all query observers.
observer.destroy(): void
Example:
observer.destroy()

Combining Results

You can provide a combine function to transform the array of results into any shape:
const observer = new QueriesObserver(
  queryClient,
  [
    { queryKey: ['todos'], queryFn: fetchTodos },
    { queryKey: ['users'], queryFn: fetchUsers },
  ],
  {
    combine: (results) => {
      return {
        data: {
          todos: results[0].data,
          users: results[1].data,
        },
        isLoading: results.some(r => r.isLoading),
        isError: results.some(r => r.isError),
      }
    },
  }
)

Type Parameters

  • TCombinedResult - The type of the combined result (defaults to Array<QueryObserverResult>)

Usage Example

import { QueryClient, QueriesObserver } from '@tanstack/query-core'

const queryClient = new QueryClient()

const observer = new QueriesObserver(
  queryClient,
  [
    {
      queryKey: ['todos'],
      queryFn: async () => {
        const response = await fetch('/api/todos')
        return response.json()
      },
    },
    {
      queryKey: ['users'],
      queryFn: async () => {
        const response = await fetch('/api/users')
        return response.json()
      },
    },
  ],
  {
    combine: (results) => ({
      todos: results[0].data,
      users: results[1].data,
      isPending: results.some(r => r.isPending),
    }),
  }
)

// Subscribe to updates
const unsubscribe = observer.subscribe((results) => {
  const [todosResult, usersResult] = results
  
  if (todosResult.isSuccess && usersResult.isSuccess) {
    console.log('Todos:', todosResult.data)
    console.log('Users:', usersResult.data)
  }
})

// Later, clean up
unsubscribe()
observer.destroy()

Dynamic Queries

You can dynamically add or remove queries:
const observer = new QueriesObserver(queryClient, [])

// Start with no queries
let queries = []

// Add a query
queries.push({
  queryKey: ['todos'],
  queryFn: fetchTodos,
})
observer.setQueries(queries)

// Add another query
queries.push({
  queryKey: ['users'],
  queryFn: fetchUsers,
})
observer.setQueries(queries)

// Remove a query
queries = queries.filter(q => q.queryKey[0] !== 'todos')
observer.setQueries(queries)

Result Array Structure

The results array maintains the same order as the queries array:
const observer = new QueriesObserver(queryClient, [
  { queryKey: ['todos'], queryFn: fetchTodos },    // results[0]
  { queryKey: ['users'], queryFn: fetchUsers },    // results[1]
  { queryKey: ['posts'], queryFn: fetchPosts },    // results[2]
])

const results = observer.getCurrentResult()
const todosData = results[0].data
const usersData = results[1].data
const postsData = results[2].data
When using the combine option, the combined result is memoized and only recomputed when the individual query results change.