RxJS - Buffer with a Pipe Chain
08/08/2021, SunGet One Event from the Group
A buffer serves to aggregate multiples of the same observable event type. However, the example shown for buffer in the official RxJS docs assumes that you have an originating source in the start of the chain which serves as the group of events for buffering as shown in here.
In the event where an observable event is happening multiple times later in the pipe chain and does not serve as the originating source, where you only want to get the first event, a need arises to selectively pick one out from the group of similar events.
//...
.pipe(
mergeMap(() => {
return getFolderCount();
}),
// Assume that tap chain runs more than once even
// though the mergeMap operator function only runs once
tap(this.logCreationBegin),
// ...
For your buffering situation, when you wish to get one of the events or the last event of the group, you will want to use either take(1) or takeLast(1) respectively. Using take(1)
simulates taking only the first of the group while takeLast(1)
will get the last within the group of events.
//...
.pipe(
mergeMap(() => {
return getFolderCount();
}),
// With the introduction of take(1), the tap operator will only run once
take(1),
tap(this.logCreationBegin),
// ...
Another option available will be to use first
, but using first
entails that the source before the first operator must emit an event, or there will be an error.
Note that, take
does not have a takeFirst analogue operator.
The last option is to use single
. You use single
to be more strict in the amount of events that are fired. The use of single
only anticipates one event that fires and will error out when there are zero or more than one event that occur. So single
behaves like a stringent first.
The difference between take, first
and single
is explained graphically by this example.