Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 52 additions & 10 deletions src/DocSearchModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@ export const DocSearchModal: Component<DocSearchModalProps> = ({
);
const numberOfHits = () => hits().length;

// AbortController for cancelling previous search requests
let abortController: AbortController | null = null;

// Cancel ongoing requests when component unmounts
onCleanup(() => {
abortController?.abort();
});

function onKeyDown(
e: KeyboardEvent & {
currentTarget: HTMLInputElement;
Expand Down Expand Up @@ -167,6 +175,9 @@ export const DocSearchModal: Component<DocSearchModalProps> = ({
}

function onReset() {
// Cancel any ongoing search request
abortController?.abort();
abortController = null;
setLoading(false);
setScreenState(ScreenState.EmptyQuery);
setHits([]);
Expand All @@ -175,30 +186,61 @@ export const DocSearchModal: Component<DocSearchModalProps> = ({
}

function search(query: string) {
// Cancel previous search request if it exists
if (abortController) {
abortController.abort();
}

// Create new AbortController for this search
abortController = new AbortController();
const currentController = abortController;

setLoading(true);
searchClient()
.index(indexUid)
.search(query, {
attributesToHighlight: ["*"],
attributesToCrop: [`content`],
cropLength: 30,
...searchParams,
})
.search(
query,
{
attributesToHighlight: ["*"],
attributesToCrop: [`content`],
cropLength: 30,
...searchParams,
},
{
signal: abortController.signal,
},
)
.catch((e) => {
onReset();
// Don't show error if request was aborted (user is still typing)
if (e.name === "AbortError") {
return;
}
// Check if this is still the current request before showing error
if (currentController.signal.aborted) {
return;
}
// Don't call onReset() as it would abort the current (possibly new) request
setLoading(false);
setScreenState(ScreenState.Error);
setHits([]);
setHitsCategories([]);
console.error(e);
})
.then((res) => {
// Check if this request was cancelled
if (currentController.signal.aborted) {
return;
}

if (!res) {
onReset();
setScreenState(ScreenState.Error);
return;
}

if (res.hits.length === 0) {
onReset();
setLoading(false);
setScreenState(ScreenState.NoResults);
setHits([]);
setHitsCategories([]);
return;
}

Expand Down