Check out myAngular article series with live demos

- JavaScript Developer and Blogger

RxJs is all about managing event streams. In this post we will look at buffering emitted values in an rxjs stream.

In the following example we will look at how to buffer a stream of mouse clicks to only emit values to subscribers once we have received three clicks.

The example is trivial. We are basically just rendering a list of numbers for the user to click. Once we receive three clicks we will return the sum of the three clicked numbers.

Below is a screenshot of the basic UI for the component.

Implementing a sum of three numbers based on clicks, in a world without rxjs, would require some manual bookkeeping to keep track of clicks.

In a nutshell the problem boils down to detecting when three clicks have happened and calculate a sum.

It turns out that rxjs is perfect for these types of problems. Modeling click events as an rxjs stream lets us control the stream using built-in rxjs operators.

One particularly useful operator in this context is bufferCount(n). By specifying a buffer count n, our stream will not emit any values to its subscribers until we have received n mouse clicks.

In the code below the subscribe block will not until trigger until we have clicked three numbers because of the bufferCount(3) call. However, the do block is called after every click, so I am using that to hide the sum between every sequence of three clicks.

import {Component} from 'angular2/core';
import {Subject} from 'rxjs/Subject';
@Component({
template:`
<h3>Click three numbers to add</h3>
<div (click)="add(number)" class="box" *ngFor="let number of numbers">{{number}}</div>
<div class="sum" *ngIf="showSum">SUM: {{calculation.sum}}</div>
`
})
export class RxJsBuffering{
numbers = [1,2,3,4,5];
sum = new Subject<number>();
series;
calculation = {};
showSum = false;
add(number){
this.sum.next(number);
}
ngOnInit(){
this.series = this.sum
.asObservable()
.do(a => this.showSum = false)
.bufferCount(3)
.subscribe(res => {
this.calculation = {sum:res.reduce((a,b) => a + b)};
this.showSum = true;
});
}
}

I have added this code on Github.

There is also a live demo here.

**If you liked this article, share it with your friends on social media:**

We also have a new Facebook group about advanced Angular topics.

I invite you to follow me on twitter Follow @helgevold