-
-
Notifications
You must be signed in to change notification settings - Fork 642
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
Async Loading Status #2089
Comments
liveQuery() does not emit anything until a query finish. If arguments change and you gain a new store, Svelte will keep showing the value from the previous store until the new store emits something. For most cases this is good because it could otherwise have been causing unnecessary flickering. liveQuery emits errors according to the TC39 Observable proposal but Svelte stores does not consume errors. The following helper should give what you need (not tested): export function svelteLiveQuery<T>(querier: () => Promise<T>): Readable<QueryResult<T>> {
return {
subscribe(emit) {
let current: QueryResult<T> = {
value: null,
error: null,
isLoading: true,
};
emit(current); // immediately emit initial value before loading
const subscription = liveQuery(querier).subscribe(
(value) => {
current.isLoading = false;
current.error = null;
current.value = value;
emit(current);
},
(error) => {
current.isLoading = false;
current.error = error;
emit(current);
}
);
return () => subscription.unsubscribe();
},
};
}
interface QueryResult<T> {
value: T | null;
error: any;
isLoading: boolean;
}
interface Readable<T> {
subscribe(this: void, subscriber: (current: T) => void): () => void;
} To use it: <script>
let transactions = $derived.by(() => {
// noop just to make it reactive
prefix;
startDate;
endDate;
return svelteLiveQuery(() =>
db.tx
.where('yyyyMMDd')
.between(format(startDate, 'yyyy-MM-dd'), format(endDate, 'yyyy-MM-dd'), true, true)
.and((tx) => !!tx.label?.startsWith(prefix ?? ''))
.sortBy('yyyyMMDd')
);
});
</script>
{#if $transactions.isLoading}
<p>Loading...</p>
{/if}
{#if $transactions.error}
<p>Error: $transactions.error</p>
{/if}
{#if $transactions.value}
<ul>
{#each $transactions.value as tx (tx.id)}
<li> ... </li>
{/each}
</ul>
{/if} There might be some even better helper (such as a liveQuery rune or something) that would feel more native to Svelte. I'm not a Svelte expert but any contribution would be welcome. |
Note: I just updated the my code snippet with type annotations and renamed |
Hello, I am using Dexie.js for the first time with my Svelte5 app, and I am trying to figure out how to show the query async status lifecycle.
For the initial load, I can check for
transactions
or$transactions
being undefined, but after I change the query inputs I would like to show some "loading" UI while the new query is running. Likewise, if an error occurs, I would like to be able to show that.What is the best practice for showing these intermediate loading + error states?
The text was updated successfully, but these errors were encountered: