(feat/search): debounce and abort previous pending req

This commit is contained in:
ManishMadan2882
2024-11-19 04:25:54 +05:30
parent 8641a91182
commit 91239820e3
2 changed files with 61 additions and 43 deletions

View File

@@ -36,7 +36,6 @@ const themes = {
const Main = styled.div`
all:initial;
font-family: sans-serif;
`
const TextField = styled.input<{ inputWidth: string }>`
@@ -206,12 +205,14 @@ export const SearchBar = ({
width = "240px"
}: SearchBarProps) => {
const [input, setInput] = React.useState<string>("");
const [loading, setLoading] = React.useState<boolean>(false)
const [loading, setLoading] = React.useState<boolean>(false);
const [isWidgetOpen, setIsWidgetOpen] = React.useState<boolean>(false);
const inputRef = React.useRef<HTMLInputElement>(null);
const resultsRef = React.useRef<HTMLInputElement>(null);
const [isResultVisible, setIsResultVisible] = React.useState<boolean>(true);
const [results, setResults] = React.useState<Result[]>([]);
const debounceTimeout = React.useRef<number | null>(null);
const abortControllerRef = React.useRef<AbortController | null>(null)
React.useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (
@@ -228,18 +229,32 @@ export const SearchBar = ({
};
}, [])
React.useEffect(() => {
input.length > 0 ?
(() => {
setLoading(true)
getSearchResults(input, apiKey, apiHost)
.then((data) => {
setResults(data)
setLoading(false)
})
if (!input) {
setResults([]);
return;
}
if (debounceTimeout.current) {
clearTimeout(debounceTimeout.current);
}
if (abortControllerRef.current) {
abortControllerRef.current.abort();
}
const abortController = new AbortController();
abortControllerRef.current = abortController;
debounceTimeout.current = setTimeout(() => {
setLoading(true);
getSearchResults(input, apiKey, apiHost, abortController.signal)
.then((data) => setResults(data))
.catch((err) => console.log(err))
})()
:
setResults([])
.finally(() => setLoading(false));
}, 500);
return () => {
abortController.abort();
clearTimeout(debounceTimeout.current ?? undefined);
};
}, [input])
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {

View File

@@ -1,34 +1,37 @@
import { Result } from "@/types";
async function getSearchResults(question: string, apiKey:string, apiHost:string): Promise<Result[]> {
const payload = {
question,
api_key:apiKey
};
try {
const response = await fetch(`${apiHost}/api/search`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
if (!response.ok) {
throw new Error(`Error: ${response.status}`);
}
const data: Result[] = await response.json();
return data;
} catch (error) {
console.error("Failed to fetch documents:", error);
throw error;
async function getSearchResults(question: string, apiKey: string, apiHost: string, signal: AbortSignal): Promise<Result[]> {
const payload = {
question,
api_key: apiKey
};
try {
const response = await fetch(`${apiHost}/api/search`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
signal: signal
});
if (!response.ok) {
throw new Error(`Error: ${response.status}`);
}
const data: Result[] = await response.json();
return data;
} catch (error) {
if (!(error instanceof DOMException && error.name == "AbortError")) {
console.error("Failed to fetch documents:", error);
}
throw error;
}
export {
getSearchResults
}
}
export {
getSearchResults
}