sveltelean Query
Version v0.2.0

Example

Search for a name, then search for another one and watch the previous results stay.

Search members

The example runs in the browser.

Requests the server received

  1. None yet.
Code
<!-- src/routes/members/search/+page.svelte -->
<script lang="ts">
	import { createQuery } from '@svelte-lean/query';
	import { listMembers } from '$api/members';

	// Nothing is requested until load(); afterwards it shows that search (cached, refetch).
	const results = createQuery(listMembers, { when: false, keepPrevious: true });
	let term = $state('');
	let searched = $state(false);

	function submit(event: SubmitEvent) {
		event.preventDefault();
		// load() resolves with the data; a failure is also written to results.error.
		searched = true;
		results.load({ search: term }).catch(() => {});
	}
</script>

<form role="search" aria-label="Search members" onsubmit={submit}>
	<input type="search" aria-label="Name" bind:value={term} />
	<button disabled={results.loading}>Search</button>
</form>

{#if !searched}
	<p>Enter a name and press Search.</p>
{:else if results.error}
	<p role="alert">{results.error.message}</p>
{:else if results.data}
	<p>{results.data.total} found{results.info.placeholder ? ', updating' : ''}</p>
	<ul>
		{#each results.data.rows as member (member.id)}
			<li>{member.name}</li>
		{/each}
	</ul>
{/if}
The component shown, against an in-memory server that answers after a fixed delay.

How it works

MomentRequestState
Before the first submitnoneblocked: 'when'
Typingnone: the params come from load(), not from stateunchanged
SubmitGET api/members?search=…, cause userloading
Submit another terma new key; the previous request is abortedloading, previous rows shown, info.placeholder: true
Submit a term searched beforea refetch of the cached keycached rows at once
  • { when: false } pauses automatic fetching; load(params) pins the params and fetches, always with a request.
  • A native <form role="search"> gives Enter to submit and a search landmark.
  • load() resolves with the data and rejects on failure; the same error is in results.error for the template.

Variations

Run the last search again

TypeScript
// Run the last search again (cause `user`: it shows `loading`).
const again = () => results.refetch();

Follow invalidations after the first search

TypeScript
// A search that should also follow invalidations after its first start holds its params in
// state and returns undefined until they exist.
let submitted = $state<string | undefined>();
const live = createQuery(listMembers, () =>
	submitted === undefined ? undefined : { search: submitted }
);
const clear = () => {
	term = '';
	submitted = undefined; // back to "nothing searched yet"; the cache keeps the results
};