Marek Panti
Marek Panti

Reputation: 126

RxJs How to create stream of observables and subscribe only to the last one after delay

I have three hostlisteners after which I am subscribing to an Observable and I would like to know if it is possible and if it is how, I could create a stream of observable, with delay and subscribe only to the last one after delay.

I want to rather use hostlistener than using observable form event, and combining it, so please could you help if if something like that would be possible and how, so the this.authenticationService.refresh() would be called only once after delay of one second?

  @HostListener('window:click', ['$event'])
  @HostListener('window:keypress', ['$event'])
  onEvent() {
    if (this.isLoggedIn && this.timeOut) {
      this.authenticationService
        .refresh()
        .pipe(take(1),
        delay(1000),
        takeLast(1))
        .subscribe((time) => {
          console.log('tu');
          this.timeOut = time.expirationTime;
          clearTimeout(this.userActivity);
          this.setTimeout(this.timeOut);
        });
    }

Upvotes: 1

Views: 815

Answers (2)

Moshezauros
Moshezauros

Reputation: 2593

I don't think observables are needed here, what you want to accomplish can be done like this:

if you don't want to reset the timer on new clicks (just ignore more clicks):

debounceTime = 3000;
private currentTimeout: number;

@HostListener("window:click", ["$event"])
@HostListener("window:keypress", ["$event"])
onEvent(event) {
  if (this.currentTimeout) {
    return;
  }

  this.currentTimeout = setTimeout(() => {
    this.currentTimeout = null;
    this.authenticationService.refresh();
  }, this.debounceTime);
}

and if you want to reset the timer every click:

debounceTime = 3000;
private currentTimeout: number;

@HostListener("window:click", ["$event"])
@HostListener("window:keypress", ["$event"])
onEvent(event) {
  if (this.currentTimeout) {
    clearTimeout(this.currentTimeout);
  }

  this.currentTimeout = setTimeout(() => {
    this.currentTimeout = null;
    this.authenticationService.refresh();
  }, this.debounceTime);
}

Upvotes: 1

MoxxiManagarm
MoxxiManagarm

Reputation: 9124

I would merge those events and pipe the merged result with the debounceTime operator.

merge(
  fromEvent(window, "click").pipe(map(() => "clicked")),
  fromEvent(window, "keypress").pipe(map(() => "pressed"))
)
  .pipe(debounceTime(1000))
  .subscribe(console.log);

Try the same on stackblitz: https://stackblitz.com/edit/rxjs-df7qwg?file=index.ts

Upvotes: 2

Related Questions