Debounced Aggregated (Buffered) Actions with RxJS 6 or How to stop making your users wait
Tags: rxjs, javascript, webdev, react
Published: 2019-06-22 16:36:47

---
title: Debounced Aggregated (Buffered) Actions with RxJS 6 or How to stop making your users wait
published: true
description: Sometimes, you don't want to react to a users input immediately and instead wait until he's finished multiple interactions before you save their progress. This is where RxJS comes in handy. Learn how to buffer user actions and save them at the right time. 
tags: rxjs, javascript, webdev, react
cover_image: https://i.imgur.com/b6ub9vq.png
---

## TLDR;

[Full Codesandbox Example](https://codesandbox.io/s/debounced-aggregated-request-osse7)


```js
// (1) Add products on click
const AddProductSubject = new Subject(); 
const onClick = (event, product) => {
    AddProductSubject.next(product); 
};

// (2) Create debounce Observable as notifier for buffer
const debounceAddProduct$ = AddProductSubject.pipe(debounceTime(1500)); 

// (3) Buffer values until notifier emits a value
const AddProduct$ = AddProductSubject.pipe(
    buffer(debounceAddProduct$)
); 

// (4) Receive results
const AddProduct$Subscriber = AddProduct$.subscribe(result => {
    console.log("subscriber", result);
    saveSelection(); // triggers the loading screen
}, console.error); 
```

## What will I learn?
Sometimes, you don't want to react to a users input immediately and instead wait until he's finished multiple interactions before you save their progress. Find out how to **buffer** these **interactions** with **RxJS 6**.

## How does it help?
This can make the difference between a tedious user experience. Where you're forced to wait for every single action to be completed. [Demo](https://codesandbox.io/s/debounced-aggregated-request-negative-example-jkwz8)

![Negative Example - Non Debounced](https://media.giphy.com/media/JUYHukWUkNHJ4CCcRj/giphy.gif)

And a pleasant user experience. Where the application only saves if you have stopped making actions for a certain timespan. [Demo](https://codesandbox.io/s/debounced-aggregated-request-osse7)

![Positive Example - Debounced](https://media.giphy.com/media/IzLraZEVFbwFS7H5Jz/giphy.gif)

## How does it work?

(1) Create a new Subject to be able to emit and receive values.
Push selected Products into the `AddProductSubject` whenever the `onClick` function is called. (in this case; whenever someone clicks on a product) 

```js
const AddProductSubject = new Subject(); 
const onClick = (event, product) => {
    AddProductSubject.next(product); 
};
```
(2) Create the `debounceAddProduct$` Observable that only emits a value if no additional values have been added to the `AddProductSubject` for `1500`ms.

```js
const debounceAddProduct$ = AddProductSubject.pipe(debounceTime(1500)); 
```

(3) Create the `AddProduct$` Observable, which buffers any emitted values until `debounceAddProduct$` emits a value and therefore closes the buffer.

```js
const AddProduct$ = AddProductSubject.pipe(
    buffer(debounceAddProduct$)
);
```
(4) Subscribe to the `AddProduct$` Observable and receive the buffered values, whenever the user has stopped selecting products for at least `1500`ms 

```js
const AddProduct$Subscriber = AddProduct$.subscribe(result => {
    console.log("subscriber", result);
    saveSelection(); // triggers the loading screen
}, console.error); 
```
{% codesandbox osse7 %}

*Any ideas on how to improve this post? Tell me! I'm always grateful for valuable feedback ;)*