0

I have a method call foo() who is making an API call, and the foo() method is calling inside a slider eventChange method, the slider has a step of 100 while the maxNum is 500k+ so when someone slide the slider it will call the eventChange method more than 1 time.

Now I want to debounce the method foo() for 400ms before making the API call like we do on FormControl value changes.

I've tried something with lodash debounce

var debounce = _.debounce(function(){

  foo();

}, 30000);

debounce();

but it's saying that foo() is not a function. How can I debounce the method foo() with raw TypeScript.

NOTE. Foo() is not bind able to any html.

Sabir Hossain
  • 1,183
  • 1
  • 25
  • 46
  • https://stackoverflow.com/questions/32051273/angular-and-debounce ... specifically you should look at the answer that's most up-to-date for Angular 6/7+ : https://stackoverflow.com/a/52244384/419705 – Roddy of the Frozen Peas Aug 27 '19 at 23:11
  • 1
    don't you think that, the answer only solving the debounce issue for FormControls and I've mentioned that already in my question , I want a TypeScript solution for a method to debounce. – Sabir Hossain Aug 27 '19 at 23:13
  • @Frozen_Peas you didn't read my question well, the links you are giving I have gone through, that's why I'm asking on SO. thanks btw. – Sabir Hossain Aug 27 '19 at 23:22
  • Unless you forgot to hit "save" on an edit, you did not (and still do not) mention reading through any questions. You mention using lodash for some reason rather than anything within Angular itself. "foo()" being bindable to html is not relevant to anything. You ask how to debounce a method in angular 2+, and the answer is "use rxjs". If your actual question is "why does using Lodash debounce not work in this case', that is 100% not what your question says. :) – Roddy of the Frozen Peas Aug 27 '19 at 23:29
  • If your question is actually "How do I use lodash to debounce this function call?" then you'll need to provide more context, namely how you're invoking that code you've posted, and where 'foo()' is defined relative to it. – Roddy of the Frozen Peas Aug 27 '19 at 23:32
  • 1
    @Frozen_Peas again you commenting without reading or understanding my question, I'm not very good at English, but the question is clear for people who understand a little English, Thanks. – Sabir Hossain Aug 27 '19 at 23:32

3 Answers3

1

Okay, somehow I manage to solve the issue through setTimeout and it's working perfect for me as a debouncer,

onSliderEventChanges(event:ChangeContext){ 

  if(this.timerid !== null){
    clearTimeout(this.timerid);
  }
  this.timerid  = setTimeout(() => 
  {
    this.foo(false);
    this.timerid = null;
  }, 400);

} 

The first if will always clear the last running timeOut, so end of the sliding I will have only one call to the foo() as only the last timeOut is alive.

setTimeout always return atimerId.

Sabir Hossain
  • 1,183
  • 1
  • 25
  • 46
1

You can use lodash-decorators to apply lodash operations to functions with ease

@debounce(1000)
foo() { ... }

It's especially useful for angular components or services which are all class based.

Ash
  • 610
  • 4
  • 9
-1

You can make use of rxjs, since you are working in angular you have that library already available, and so you have a debounce function ready to use on it.

ngOnInit(): void {
    // you look for your html element in which you desire
    // to attach an eventListener 
    let myHtmlElement = document.querySelector("#my-element-id-name");
    // then we proceed to turn the event into an observable sequence
    // my event could be in your case the 'click' event, I believe
    const myEventVar$ = fromEvent(myHtmlElement , 'myEvent');
    myEventVar$.pipe(
      // debounceTime is the rxjs library to delay the firing 
      // of function foo by 400ms in this example
      debounceTime(400)
    ).subscribe( () => {
      this.foo();
    });
}
Pepe Alvarez
  • 1,218
  • 1
  • 9
  • 15