U rock
U rock

Reputation: 775

prevent same button click frequently with observable in angular

I Have 5 list of buttons with each click of button we have to allow first time to log that particular button . If user click on again same button we have to show prompt that hey you have to wait 3 seconds after 3 seconds he may allow to click it again. This must be work for 5 buttons individually.

So how can we achieve this with Observable. We have fromevent method which i don't know how to use it for this particular task.

<div *ngFor="let button of buttonlist">
  <button (click)="buttonClicked(button)">{{button}}</button>
</div>



buttonClicked(button) {
    for(var i=0; i<this.buttonlist.length; i++) {
      if(button == this.buttonlist[i]) {
        // here first time we have to allow if click it on same button again don't allow wait for 3 seconds then allow 
      }
    }
  }

you can find here working example https://stackblitz.com/edit/angular-6srmgj?file=src%2Fapp%2Fapp.component.ts

Upvotes: 0

Views: 1009

Answers (2)

Hikmat G.
Hikmat G.

Reputation: 2621

Think this is what you wanted code

<div *ngFor="let button of buttonlist">
  <button #btn>{{button}}</button>
</div> 

  buttonlist = ["button1", "button2", "button3", "button4", "button5"];
  @ViewChildren('btn') buttons:QueryList<any>;

  ngAfterViewInit() {
    this.buttons.forEach(button => {
      fromEvent(button.nativeElement, 'click').pipe(
        map(e => ({ e: e, t: setTimeout(() => console.log('wait...')) })),
        throttleTime(3000)
      ).subscribe((args: any) => {
        clearTimeout(args.t);
        console.log(args.e.target.innerHTML)
      });
    });
  }

Upvotes: 3

Andriy
Andriy

Reputation: 15442

The question was

If user click on again same button we have to show prompt that hey you have to wait 3 seconds after 3 seconds he may allow to click it again.

So in order to solve

we have to show prompt that hey you have to wait 3 seconds

part of question, I propose to extend Hikmat's answer and use 2 observables, one with throttleTime() and one without, the first one will unsubscribe the latter one if needed and than resubscribe again:

@ViewChildren('btn') buttons: QueryList<any>;

private subs = [];
private subscriptions = new Subscription();;

buttonlist = ["button1", "button2", "button3", "button4", "button5"];

ngAfterViewInit() {
  this.buttons.forEach((button, ind) => {
    this.subscriptions.add(
      fromEvent(button.nativeElement, 'click').pipe(
        throttleTime(3000)
      ).subscribe((e: any) => {
        this.subs[ind].unsubscribe();
        setTimeout(_ => this.listenToClick(button, ind));
        console.log(`BUTTON # ${ind}: Now is good time to do something`);
      })
    );
    this.listenToClick(button, ind);
  });
}

ngOnDestroy() {
  // unsubscribe from throttled subscriptions
  this.subscriptions.unsubscribe();
  // unsubscribe from other subscriptions
  this.subs.map(sub => sub.unsubscribe());
}

private listenToClick(button, ind) {
  this.subs[ind] = fromEvent(button.nativeElement, 'click')
    .subscribe(res => console.log(`BUTTON # ${ind}: You have to wait for 3 secs`));
}

STACKBLITZ

Upvotes: 0

Related Questions