I'm using a service to get address details but im having difficulty using debounce, I'm not sure I'm doing it correctly.
I would like to make 2 API requests, when the user types into the input field it calls fetchAddressSuggestions then once the user selects on the address they would like it calls fetchCompleteAddress (which contains postCode/ZipCode)
I don't think the debounce is working here? Can I use debounce async?
Some example code.
const fetchAddressSuggestions = debounce(async (addressId) => {
try {
const response = await axios.get(
`/api/v2/address/search/${countryShortCode}/${addressId.trim()}/`,
DEFAULT_REQUEST
);
const suggestions = response.data.results; // Assuming the response contains address suggestions
setOptions(suggestions);
} catch (error) {
console.error('Error fetching address suggestions:', error);
}
}, 1200);
const fetchCompleteAddress = async (selectedResult) => {
try {
const response = await axios.get(
`/api/v2/address/complete/${countryShortCode}/${selectedResult.id}/`,
DEFAULT_REQUEST
);
const completeAddress = response.data.result;
props.updateDeliveryAddress({
// Updating address with completeAddress
});
} catch (error) {
console.error('Error fetching complete address:', error);
}
};
// Debounce the fetchAddressSuggestions function
const debouncedFetch = debounce(fetchAddressSuggestions, 800);
const handleInputChange = (event, newInputValue) => {
setAddressId(newInputValue);
debouncedFetch(newInputValue); // Debounced function call
const selectedResult = options.find((option) => option.address === newInputValue);
if (selectedResult) {
fetchCompleteAddress(selectedResult);
setShowSavedAddress(true);
}
};
...
Using material UI Autocomplete component
...
<FormControl fullWidth margin="dense">
<Autocomplete
id="address-suggestions"
open={open}
onOpen={() => {
setOpen(true);
}}
onClose={() => {
setOpen(false);
}}
filterOptions={(x) => x}
isOptionEqualToValue={(option, value) =>
value === undefined || option?.address?.toString() === (value?.address ?? value)?.toString()
}
getOptionLabel={(option) => option.address}
options={options}
renderOption={(props, option) => {
return (
<li {...props} key={option.id}>
{option.address}
</li>
);
}}
loading={loading}
inputValue={addressId}
onInputChange={handleInputChange}
disabled={collectionOnly || isDigitalOnlyOrder}
renderInput={(params) => (
<TextField
{...params}
label="Start typing address"
variant="filled"
disabled={collectionOnly || isDigitalOnlyOrder}
placeholder="e.g. 1 High Street, London, SWA 1AA"
InputProps={{
...params.InputProps,
endAdornment: (
<Box
sx={{
'& > div.loadingSpinner': {
display: 'flex',
gap: '10px',
alignItems: 'center',
position: 'absolute',
top: '0',
right: '40px',
height: '100%',
},
}}
>
{loading && (
<div className="loadingSpinner">
<CircularProgress color="inherit" size={20} />
</div>
)}
{params.InputProps.endAdornment}
</Box>
),
}}
/>
)}
/>
</FormControl>
Essentially it works I would like to just optomise the debounce function and not make a request to the API on every keystroke