2

I have a working ajax call that I've made which sends a value to an endpoint for every input change. SO if the user is typing, it sends the call per keystroke.

I put a setTimeout around it for 2 seconds, which delays the call just fine. But the problem is it still sends a call for every keystroke.

I want to get it to where, after 2 seconds, it sends a call for what's been typed so far. If the user starts typing again maybe it would set again.

I"m just trying to send fewer keystrokes and make it to where when the user stops typing there's just a slight delay and call.

Here's the call now:

$('#input').on('input', function() {
  let _this = $(this);


  if (_this.val() === '') {
    return;
  } else {

    const searchResult = $(this).val();
    console.log(searchResult);
    //if I type "PLANT" the console shows "P" "PL" "PLA" "PLAN" "PLANT"

    //after 2 seconds, send searchResult via ajax
    setTimeout(function () {
        $.ajax({ url: '/endpoint', 
          data: {
            search_result:searchResult
          },
          "_token": "{{ csrf_token() }}",
          type: "POST", 
          success: successHandler 

        });
    }, 2000);
  }
});
Whisou138
  • 451
  • 5
  • 21
  • 5
    You might be looking for the term "throttle" or "debounce", see for example this question: https://stackoverflow.com/questions/7373023/throttle-event-calls-in-jquery – chrki Sep 04 '18 at 20:16
  • Save the timout in a variable. Start a timeout for every key stroke but also clear the previous one if there's one. The last timeout won't be cleared so has time to run the full delay and send the data to the server with the Ajax call – Mark Sep 04 '18 at 20:21
  • How would I add it to every keystroke though? – Whisou138 Sep 04 '18 at 21:41

1 Answers1

1

You should debounce the ajax call. The idea is that the timeout is cleared if the user enters another value. That way the ajax call will only be made once after the user has stopped typing for the given timeout period (2 seconds for your case). That would look something like this:

var timeout;

$('#input').on('input', function() {
  let _this = $(this);


  if (_this.val() === '') {
    return;
  } else {

    const searchResult = $(this).val();
    console.log(searchResult);
    //if I type "PLANT" the console shows "P" "PL" "PLA" "PLAN" "PLANT"

    if (timeout) {
      clearTimeout(timeout);
    }
    
    //after 2 seconds, send searchResult via ajax
    timeout = setTimeout(function () {
        $.ajax({ url: '/endpoint', 
          data: {
            search_result:searchResult
          },
          "_token": "{{ csrf_token() }}",
          type: "POST", 
          success: successHandler 

        });
    }, 2000);
  }
});
Cody S
  • 494
  • 3
  • 5
  • This may be a dumb question: is debouncing just a technique or is there supposed to be a function named debounce – Whisou138 Sep 05 '18 at 00:05
  • @Whisou138 Debouncing is a technique. You can read more about it here: https://css-tricks.com/debouncing-throttling-explained-examples/ – Cody S Sep 05 '18 at 18:47