From ae3f15a65d08c82d94e81ee0c154b3fbcfcb79ea Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 25 Feb 2026 14:38:00 +0000 Subject: [PATCH] fix(docs): use eq() operator in .where() clauses instead of bare boolean expressions The .where() clause requires expression objects (via eq(), gt(), etc.), not raw JavaScript boolean expressions. Bare property references like `todo.completed` or negated expressions like `!todo.completed` fail the isExpressionLike() validation at runtime, throwing InvalidWhereExpressionError. Fixed in docs/overview.md, docs/guides/schemas.md, docs/collections/trailbase-collection.md, docs/reference/classes/BaseQueryBuilder.md, and source JSDoc in packages/db/src/query/builder/index.ts. Fixes #1297 https://claude.ai/code/session_01VD8cnL4qhw4k5XKaK9qL8L --- docs/collections/trailbase-collection.md | 4 ++-- docs/guides/schemas.md | 7 ++++--- docs/overview.md | 2 +- docs/reference/classes/BaseQueryBuilder.md | 4 ++-- packages/db/src/query/builder/index.ts | 4 ++-- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/docs/collections/trailbase-collection.md b/docs/collections/trailbase-collection.md index 1b1d60d42..b5d6091bc 100644 --- a/docs/collections/trailbase-collection.md +++ b/docs/collections/trailbase-collection.md @@ -147,7 +147,7 @@ const todosCollection = createCollection( ## Complete Example ```typescript -import { createCollection } from '@tanstack/react-db' +import { createCollection, eq } from '@tanstack/react-db' import { trailBaseCollectionOptions } from '@tanstack/trailbase-db-collection' import { initClient } from 'trailbase' import { z } from 'zod' @@ -195,7 +195,7 @@ export const todosCollection = createCollection( function TodoList() { const { data: todos } = useLiveQuery((q) => q.from({ todo: todosCollection }) - .where(({ todo }) => !todo.completed) + .where(({ todo }) => eq(todo.completed, false)) .orderBy(({ todo }) => todo.created_at, 'desc') ) diff --git a/docs/guides/schemas.md b/docs/guides/schemas.md index b51296b43..f028e5dfe 100644 --- a/docs/guides/schemas.md +++ b/docs/guides/schemas.md @@ -831,7 +831,7 @@ A complete todo application demonstrating validation, transformations, and defau ```typescript import { z } from 'zod' -import { createCollection } from '@tanstack/react-db' +import { createCollection, eq } from '@tanstack/react-db' import { queryCollectionOptions } from '@tanstack/query-db-collection' // Schema with validation, transformations, and defaults @@ -921,7 +921,7 @@ const todoCollection = createCollection( function TodoApp() { const { data: todos } = useLiveQuery(q => q.from({ todo: todoCollection }) - .where(({ todo }) => !todo.completed) + .where(({ todo }) => eq(todo.completed, false)) .orderBy(({ todo }) => todo.created_at, 'desc') ) @@ -991,6 +991,7 @@ function TodoApp() { ```typescript import { z } from 'zod' +import { eq } from '@tanstack/db' // Schema with computed fields and transformations const productSchema = z.object({ @@ -1046,7 +1047,7 @@ const productCollection = createCollection( function ProductList() { const { data: products } = useLiveQuery(q => q.from({ product: productCollection }) - .where(({ product }) => product.in_stock) // Use computed field + .where(({ product }) => eq(product.in_stock, true)) // Use computed field .orderBy(({ product }) => product.final_price, 'asc') ) diff --git a/docs/overview.md b/docs/overview.md index 8af0254c3..cb513ff11 100644 --- a/docs/overview.md +++ b/docs/overview.md @@ -57,7 +57,7 @@ const todoCollection = createCollection({ const Todos = () => { // Bind data using live queries const { data: todos } = useLiveQuery((q) => - q.from({ todo: todoCollection }).where(({ todo }) => todo.completed) + q.from({ todo: todoCollection }).where(({ todo }) => eq(todo.completed, false)) ) const complete = (todo) => { diff --git a/docs/reference/classes/BaseQueryBuilder.md b/docs/reference/classes/BaseQueryBuilder.md index 0962768ed..550796b25 100644 --- a/docs/reference/classes/BaseQueryBuilder.md +++ b/docs/reference/classes/BaseQueryBuilder.md @@ -288,7 +288,7 @@ A QueryBuilder with the specified source query.from({ users: usersCollection }) // Query from a subquery -const activeUsers = query.from({ u: usersCollection }).where(({u}) => u.active) +const activeUsers = query.from({ u: usersCollection }).where(({u}) => eq(u.active, true)) query.from({ activeUsers }) ``` @@ -550,7 +550,7 @@ query ``` // Join with a subquery -const activeUsers = query.from({ u: usersCollection }).where(({u}) => u.active) +const activeUsers = query.from({ u: usersCollection }).where(({u}) => eq(u.active, true)) query .from({ activeUsers }) .join({ p: postsCollection }, ({u, p}) => eq(u.id, p.userId)) diff --git a/packages/db/src/query/builder/index.ts b/packages/db/src/query/builder/index.ts index c43f3ad48..c58ebc087 100644 --- a/packages/db/src/query/builder/index.ts +++ b/packages/db/src/query/builder/index.ts @@ -129,7 +129,7 @@ export class BaseQueryBuilder { * query.from({ users: usersCollection }) * * // Query from a subquery - * const activeUsers = query.from({ u: usersCollection }).where(({u}) => u.active) + * const activeUsers = query.from({ u: usersCollection }).where(({u}) => eq(u.active, true)) * query.from({ activeUsers }) * ``` */ @@ -171,7 +171,7 @@ export class BaseQueryBuilder { * ``` * * // Join with a subquery - * const activeUsers = query.from({ u: usersCollection }).where(({u}) => u.active) + * const activeUsers = query.from({ u: usersCollection }).where(({u}) => eq(u.active, true)) * query * .from({ activeUsers }) * .join({ p: postsCollection }, ({u, p}) => eq(u.id, p.userId))