Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

useLiveQuery needs a default value. #544

Open
thruflo opened this issue Feb 17, 2025 · 4 comments
Open

useLiveQuery needs a default value. #544

thruflo opened this issue Feb 17, 2025 · 4 comments
Labels
enhancement New feature or request

Comments

@thruflo
Copy link
Contributor

thruflo commented Feb 17, 2025

Currently, useLiveQuery returns undefined until the initial query has returned. This leads to a bunch of if results !=== undefined checks in your component code.

For example:

function Component() {
  const results = useLiveQuery(`
    SELECT * FROM items
      WHERE foo = $1
  `, ['bar'])
  const items = results !== undefined ? results.rows : []
  // ...

Now, if you look at useState, it avoids this by supporting a default value:

function Component() {
  const [results, setResults] = useState([])
  // ...

I propose the ergonomic improvement of supporting a default value with useLiveQuery:

function Component() {
  const { rows: items } = useLiveQuery(`
    SELECT * FROM items
      WHERE foo = $1
  `, ['bar'], [])
  // ...

Using a third positional argument for it is slightly tricky with query parameters (hence cherry picking an example of a query that uses parameters), because then you need to specify the query parameters arg even if not using them. I guess an alternative would be a {default: value} option (more explicit but also more verbose).

@copiltembel
Copy link
Collaborator

an alternative would be a {default: value} option (more explicit but also more verbose).

I think it's ok to be more verbose when you need that option. If we default to [] I guess would be fine for most users.

@thruflo
Copy link
Contributor Author

thruflo commented Feb 17, 2025

I think any default value should be explicit. It's useful, when you want to, to be able to distinguish between empty results and no results yet.

@copiltembel
Copy link
Collaborator

const items = results !== undefined ? results.rows : []

const items = results?.rows ?? []

@samwillis
Copy link
Collaborator

The live.query() api excepts both optional arguments of a single options object arguments:

/**
* Create a live query
* @param query - The query to run
* @param params - The parameters to pass to the query
* @param callback - A callback to run when the query is updated
* @returns A promise that resolves to an object with the initial results,
* an unsubscribe function, and a refresh function
*/
query<T = { [key: string]: any }>(
query: string,
params?: any[] | null,
callback?: (results: Results<T>) => void,
): Promise<LiveQuery<T>>
/**
* Create a live query
* @param options - The options to pass to the query
* @returns A promise that resolves to an object with the initial results,
* an unsubscribe function, and a refresh function
*/
query<T = { [key: string]: any }>(
options: LiveQueryOptions<T>,
): Promise<LiveQuery<T>>

useLiveQuery also has multiple call signatures:

export function useLiveQuery<T = { [key: string]: unknown }>(
query: string,
params?: unknown[] | null,
): LiveQueryResults<T> | undefined
export function useLiveQuery<T = { [key: string]: unknown }>(
liveQuery: LiveQuery<T>,
): LiveQueryResults<T>
export function useLiveQuery<T = { [key: string]: unknown }>(
liveQueryPromise: Promise<LiveQuery<T>>,
): LiveQueryResults<T> | undefined

although not a option arg one. Maybe we should add that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants