-2

I am trying to integrate debounce to a search input so i can search through fetched data (after getting the data ) with the full term, i have this debounce function in the App.js :

  debounce = (callback, delay) => {
    let timer;
    return (...args) => {
      clearTimeout(timer);
      timer = setTimeout(() => callback(...args), delay);
    }
  }

  debouncedTerm = this.debounce(text => console.log(text), 300);

I have also this method in the App.js

onSearchChanged = data => {
    const searchBar = data.target.value.toLowerCase();
    this.debouncedTerm(searchBar)
    this.setState({
      searchBar: searchBar,
    }, () => {
        let newData = {...this.state};

        if( typeof this.props.source !== "undefined"){
            newData.source = this.props.source
        }

        newData.params = {
            searchBar : this.state.searchBar
        }

        Api.fetchQuestions(newData.params)
        .catch( error => {
            if (typeof error.message !== "undefined"){
                newData.config.formMessage = {
                    message : error.message,
                    success : false,
                }
                newData.widgetStatus = false;
                this.setState(newData)
            }
            return {data:{data:[]}}
        })
        .then( response => {
            if(response.data.status === 'success'){
                return response.data.data;
            }
            this.setState({
            questions: [...response.data.questions.items],
            loading: false
            });
        })
    });
};

FYI : I pass the value of the input (searchBar) as a parameter in newData.params

'URL/questions?client_id='+params.client_id+'&term='+params.searchBar,

How can i integrate debouncedTerm in the method onSearchChanged

I have the search input in a child component

<InputSearch 
    type="search" 
    placeholder="Search"
    onChange={props.searchCallback}
/>
Elichy
  • 548
  • 4
  • 17

1 Answers1

0

this is a part of the code I wrote recently:

export function debounceFetch(fn, delay) {
  let createdTimeout;
  let controller;
  function onCancel() {
    controller?.abort();
    createdTimeout?.cancel();
  }

  async function debounced(...args) {
    onCancel();
    controller = new AbortController();
    createdTimeout = timeout(delay);
    await createdTimeout.delay;
    return fn(...args, controller.signal);
  }
  return [
    debounced,
    onCancel,
  ];
}

It cancels the fetch request too, and this is the timeout part:

function timeout(ms) {
  let timeoutRef;
  let rejectRef;

  const delay = new Promise((resolve, reject) => {
    timeoutRef = setTimeout(() => {
      resolve('timeout done');
    }, ms);
    rejectRef = () => {
      reject(new Error('cancel timeout'));
    };
  });

  return {
    delay,
    cancel() {
      clearTimeout(timeoutRef);
      rejectRef();
    },
  };
}
SoroushOwji
  • 123
  • 8
  • thanks ;) i don't know how to adapt it with my code – Elichy Oct 08 '21 at 16:11
  • the debounce fetch takes in a fetch request and a delay time and returns a debouncable `fetch` and a `cancel` function. You can use it like `useState` and stuff :D – SoroushOwji Oct 09 '21 at 10:21