Using lodash debounce in react on input change

128 views Asked by At

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

0

There are 0 answers