Skip to content
Advertisement

Prevent last longer call to overrite shorter new call

I’m working with React, and in my component every time the user types a input the code calls a API. But this API takes more time to return with few words than with bigger words.

So lets say i type “ne”, and takes 7 seconds to return 100+ results, but before that 7 seconds, i wait a second and finish type “new york”. That takes miliseconds, than finishes before the previus API call.

Ok, “new york” appears to me on the search, BUT now the first call finishes and overrites the last result.

How can i make that work? Without breaking any of the steps (aka, search in a click of a button stead while tiping), if this is possible

Short example of my code:

class MyComponent extends Component {
    state = {
      items = []
    }
    
    construtor(props) {
      this.myCall = _debounce(this.myCall, 400);
    }
    
    myCall = async e => {
      e.persist();
      const query = _get(e, 'target.value', '');
    
      try {
        items = await myAPI(query)
        this.setState({items})
      } catch (error) {
        console.error(error)
      }
    }
    ...
    return (
      <>
        <input onChange={(e) => myCall(e)} />
        {items.map(item => (
          <p>item</p>
        ))}
      </>
    );
}

Advertisement

Answer

You could check that the input value hasn’t changed while you awaited the response:

items = await myAPI(query)

if (query === _get(e, 'target.value', '')) {
  this.setState({items})
}

Same thing with an implementation that avoids multiple _get calls:

const query = this.query = _get(e, 'target.value', '');

items = await myAPI(query)

if (query === this.query) {
  this.setState({items})
}
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement