T
TanStack2mo ago
xenial-black

How to conditionally call useLiveQuery

I have the following code:
const useElectricChatsByReportId = (reportId: string | null) => {
const org = useCurrentOrg();
const data = useLiveQuery(
(q) =>
q
.from({
chats: chatsCollection
})
// Don't want to filter by null since that will match a bunch of chats
.where(({ chats }) => eq(chats.reportId, reportId ?? 'undefined')),
[org.id, reportId],
);

return data.data;
};
const useElectricChatsByReportId = (reportId: string | null) => {
const org = useCurrentOrg();
const data = useLiveQuery(
(q) =>
q
.from({
chats: chatsCollection
})
// Don't want to filter by null since that will match a bunch of chats
.where(({ chats }) => eq(chats.reportId, reportId ?? 'undefined')),
[org.id, reportId],
);

return data.data;
};
Ideally, I don't even want to run the live query if reportId is null. How can I do this withough violating the rules of react hooks? i.e. I can't do this since it would mean conditionally calling a hook:
const useElectricChatsByReportId = (reportId: string | null) => {
if (!reportId) return [];
const org = useCurrentOrg();
const data = useLiveQuery(
(q) =>
q
.from({
chats: chatCollection,
})
// Don't want to filter by null since that will match a bunch of chats
.where(({ chats }) => eq(chats.reportId, reportId ?? 'undefined')),
[org.id, reportId],
);

return data.data;
};
const useElectricChatsByReportId = (reportId: string | null) => {
if (!reportId) return [];
const org = useCurrentOrg();
const data = useLiveQuery(
(q) =>
q
.from({
chats: chatCollection,
})
// Don't want to filter by null since that will match a bunch of chats
.where(({ chats }) => eq(chats.reportId, reportId ?? 'undefined')),
[org.id, reportId],
);

return data.data;
};
13 Replies
afraid-scarlet
afraid-scarlet2mo ago
Live Queries | TanStack DB Docs
TanStack DB Live Queries TanStack DB provides a powerful, type-safe query system that allows you to fetch, filter, transform, and aggregate data from collections using a SQL-like fluent API. All queri...
conscious-sapphire
conscious-sapphire2mo ago
This is good for conditional "where" clauses, but not for saying "I don't want this to even run if a condition is not met" - essentially the enabled: !!itemId of useQuery. Perhaps these live queries are so performant that we could just use a conditional where clause that is known to filter everything? eg: .where(({ item }) => isUndefined(item.id))) which actually for @Robert Cooper 's situation would be equivalent of just doing .where(({ chats }) => eq(chats.reportId, reportId)) right, since when reportId is null, it'll return 0 results?
xenial-black
xenial-blackOP2mo ago
For us, when reportId is null it returns a bunch of chats (since we can have chats not related to reports in our app). And you're exactly right, I need something equivalent to enabled on useQuery.
xenial-black
xenial-blackOP2mo ago
I was just filtering by a dummy ID of the string 'undefined' , but I'm getting some weird call stack error related to the live query (which might be a separate issue with tanstack db). See attached .txt file for the error I get (if you're interested). But what would avoid this is just not running the query at all if reportId is null.
afraid-scarlet
afraid-scarlet2mo ago
you can return undefined to disable a query:
const { data, isIdle } = useLiveQuery((q) => {
if (!enabled) return undefined; // disables subscription
return q.from({ todos }).where(({ eq }, t) => eq(t.userId, userId));
}, [enabled]);
const { data, isIdle } = useLiveQuery((q) => {
if (!enabled) return undefined; // disables subscription
return q.from({ todos }).where(({ eq }, t) => eq(t.userId, userId));
}, [enabled]);
xenial-black
xenial-blackOP2mo ago
Ok, I will give it a try. I do get type errors for that though.
No description
xenial-black
xenial-blackOP2mo ago
And it fails on runtime as well.
No description
xenial-black
xenial-blackOP2mo ago
Perhaps, i'm on an out of date version. I will try upgrading.
xenial-black
xenial-blackOP2mo ago
Upgraded to latest version and still get an error (albeit a bit different).
No description
xenial-black
xenial-blackOP2mo ago
Ah wait, that's an error in my code Looks like it worked
eager-peach
eager-peach2mo ago
is it possible to wrap this call inside a component that only renders when the reportId is present?
xenial-black
xenial-blackOP2mo ago
It would have been a very inconvenient and unideal refactor. Thankfully I don't have to since the ability to return undefined in the useLiveQuery was good enough for me.

Did you find this page helpful?