Search code examples
javascriptinputsalesforcedebouncinglwc

JavaScript, LWC, Searching after User to stop typing, debounce


In input user writes a search phrase for searching products. And I would like to set searching after user stopped typing. Here is a nice example, but not works in Lightning Web Components. When I begin to write to the search input, there is an error: "This page has an error. You might just need to refresh it."

productList.html:

<lightning-input
  type="search"
  class="slds-var-m-bottom_small"
  value={searchKey}
  placeholder="Searching..."
  onchange={handleSearchEvent}>
</lightning-input>

productList.js:

import { LightningElement, wire } from 'lwc';
import findProducts from '@salesforce/apex/ProductMaster.findProducts';

export default class ProductList extends LightningElement {
  searchKey = '';
  timeout = null;

  @wire(findProducts, { searchKey: '$searchKey' })
  products;

  handleSearchEvent(event) {
    const eventValue = event.target.value;
    clearTimeout(timeout);
    timeout = setTimeout(function (eventValue) {
      this.searchKey = eventValue;
      console.clear();
      console.log('handleSearchEvent() -> this.searchKey: ' + this.searchKey);
    }, 1000); // searching after 1s
  }
}

How is it needed to set timeout? And js console writes:

console.log('handleSearchEvent() -> this.searchKey: ' + this.searchKey);

handleSearchEvent() -> this.searchKey: undefined


Solution

  • The problem is that your this binding in your function needs to be explicitly set:

    timeout = setTimeout(function (eventValue) {
          this.searchKey = eventValue;
          console.clear();
          console.log('handleSearchEvent() -> this.searchKey: ' + this.searchKey);
        }.bind(this), 1000);
    

    But perhaps an easier way would be to just use an arrow function which will implicitly bind this I believe:

    timeout = setTimeout((eventValue) => {
          this.searchKey = eventValue;
          console.clear();
          console.log('handleSearchEvent() -> this.searchKey: ' + this.searchKey);
        }, 1000);