0

component controller:

private updateSplitScreenService = () => {
    this.splitScreenService.emitNewState(this.products);
    this.splitScreenService.emitNewState(this.stores);
};

splitScreenService:


// emitNewState is called multiple times in quick succession but
// we want to only fire one API request and return the observable back 
// to the component
public emitNewState = (items: Products[] | Stores[]): void => {
    // If we already have a debounce active but a new call to emit 
    // the state has come in, cancel the current one.
    if (this.debounceTimeout) {
        clearTimeout(this.debounceTimeout);
    }

    // Create a new timeout
    this.debounceTimeout = setTimeout(() => {
        this.http.post().subscribe();
    }, 500);
};

As you can see above I am calling from my component a service function which has a custom "debounce" functionality to ensure that an API request will only happen if said function does not get called again within 500ms of the last call. Any call within 500ms will cancel the previously set up debounce function to make an API request and set up a timeout function again to wait and call the API request. This ensures that the API is called only once.

But if I wanted to return the observable of the API request back to my component controller I am running into the issue of how to return it from within the custom debounce/timeout function itself. The goal is to debounce a call so that not only does the subscriber only receive 1 result, but the previous calls were canceled (or not made at all).

  • Could you please update the example so that it would be possible to run and play with it. It would help to understand your problem easier – Shlang Mar 31 '20 at 18:19
  • To add to Shlang's advice, we need to have a reasonable representation of the code in the question itself. There is a code editor in Stack Overflow that allows code to be run _in situ_, but if that does not work, you can show static code in the question, and then link to the Plnkr at the end. Thanks! – halfer Mar 31 '20 at 18:40
  • Thanks for the feedback, I removed the plnkr link and move the relevant code into the question body itself. – user3406930 Mar 31 '20 at 20:02

1 Answers1

0

Try taking advantage of debounceTime built in to Rxjs

import { debounceTime, switchMap } from 'rxjs';
...
emitNewState$ = new Subject();
...

ngOnInit() {
  this.listenToEmitNewState$();
}
....
emitNewState() {
  this.emitNewState$.next();
}

listenToEmitNewState$() {
  this.emitNewState$.pipe(
    debounceTime(500),
  ).subscribe(() => {
    // do what you want, but if you're going to do an HTTP call, use switchMap like how it is commented below
  });

  //this.emitNewState$.pipe(
    // debounceTime(500),
     //switchMap(() => this.http.post()),
  // ).subscribe(() => {....});
}

AliF50
  • 16,947
  • 1
  • 21
  • 37