1

I have a tab bar with tabs and one active tab and I want to prevent multiple clicks on a single tab within a .

I would like to implement the following behavior:

Original state with each case: Active tab is tab A.

  • If I once press on tab A, I want the A tab event.
  • If I repeatably press on tab A, I want to have throttled A events.
  • If I press tab B, I want to have the B event.
  • If I repeatably press tab B, I want to have the first B event and throttle the other B events.

In other words:

  • press tab event -> if same tab -> throttle-> tab event
  • press tab event -> if not same tab -> tab event

How do I implement this behavior with RxJS?

this.onTabSelect$.pipe( 
    // TODO ?
).subscribe(async (tab: Tab) => {
    // tab event
});

Thanks!

Here is my current (finally working) state: code example

mangei
  • 747
  • 7
  • 16

2 Answers2

1

I found the answer here and updated my example:

Answer

code example

mangei
  • 747
  • 7
  • 16
0

Use throttle and choose interval(throttle_time) or of(0) depending on the value of the selected tab.

this.onTabSelect$.pipe(
    throttle((tab: Tab) => interval(tab.id === this.currentTab ? interval(THROTTLE_TIME) : of(0))
).subscribe(async (tab: Tab) => {
    // tab event
});

throttle takes as argument a function which, given the emitted value of the initial observable, returns an observable that will be subscribed to, and once such observable emits a value, the throttle timer will be disabled.

So we can decide, depending on whether the selected tab is the current tab or not, whether to throttle the observable for a given time, or emit right away effectively disabling the throttle timer because the tab is a different one.

Marc Sances
  • 2,402
  • 1
  • 19
  • 34
  • Thanks for your answer. It got me one step closer. There is just one edge-case that I did not manage to find a solution. see here: https://codesandbox.io/s/fancy-sky-i4zsv?file=/src/app/app.component.ts edge case: tab A is selected (default), and then fast double click on tab B. If the tab changes, it always emits two events instead of one initially. – mangei Aug 16 '21 at 14:01