#Differentiating between “undefined” as loading vs as the actual query return value in react

3 messages · Page 1 of 1 (latest)

austere axle
#

The useQuery hook returns nothing when leading but sometimes my query intentionally returns nothing as well. How can I detect that case in the front end?

plucky shuttleBOT
#

Hi @austere axle. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

In Convex, the return value of the useQuery hook is always undefined while the query is loading. Once the query has loaded, it will never be undefined again—even if your query function returns "nothing" (e.g., null, [], or {}), because undefined is not a valid return type for Convex queries. Convex queries must return a supported data type, and undefined is not one of them. This means:

  • If useQuery returns undefined, you can be certain the query is still loading.
  • If your query function intentionally returns "nothing," you should return a value like null, an empty array [], or an empty object {}—but never undefined.

So, in your frontend, you can reliably use a check like this:

const data = useQuery(api.myQuery, args);

if (data === undefined) {
  // The query is still loading
} else if (data === null) {
  // The query intentionally returned null
} else if (Array.isArray(data) && data.length === 0) {
  // The query intentionally returned an empty array
} else {
  // The query returned actual data
}

This pattern is recommended in the Convex documentation:

The useQuery React hook will return undefined when it is first mounted, before the query has been loaded from Convex. Once a query is loaded it will never be undefined again (even as the data reactively updates). undefined is not a valid return type for queries... You can use this as a signal for when to render loading indicators and placeholder UI.
UI patterns - Best Practices

So, you do not need to worry about confusing "loading" with an intentional "no result"—just ensure your query never returns undefined.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: