Search code examples
javascriptsvelte

How to debounce / throttle with Svelte?


So i currently have:

App.html

<div>
  <input on:input="debounce(handleInput, 300)">
</div>

<script>
  import { debounce } from 'lodash'

  export default {
    data () {
      name: ''
    },

    methods: {
      debounce,
      async handleInput (event) {
        this.set({ name: await apiCall(event.target.value).response.name })
      }
    }
  }
</script>

And get the error Uncaught TypeError: Expected a function at App.debounce. This comes from Lodash so it doesn't seem like the method from Svelte is being passed through.

Extra extra edit

Extra context for how i'm currently achieving it:

oncreate () {
  const debounceFnc = this.handleInput.bind(this)

  this.refs.search.addEventListener('input', debounce(debounceFnc, 300))
}

Solution

  • It's the method itself that should be debounced — so rather than calling debounce on each input event, set handleInput up to be a debounced method:

    Svelte v3 version

    <input on:input={handleInput}>
    
    <script>
      import debounce from 'lodash/debounce'
    
      let name = '';
        
      const handleInput = debounce(e => {
        name = e.target.value;
      }, 300)
    </script>
    

    REPL example here.

    Older Svelte version

    <div>
      <input on:input="handleInput(event)">
    </div>
    
    <script>
      import { debounce } from 'lodash'
    
      export default {
        data () {
          return { name: '' };
        },
    
        methods: {
          handleInput: debounce (async function (event) {
            this.set({ name: await apiCall(event.target.value).response.name })
          }, 300)
        }
      }
    </script>
    

    Simplified REPL example here.