I have a BehaviorSubject which emits JavaScript objects periodically. I want to construct another observable which will emit both previous and current values of the underlying observable in order to compare two objects and determine the delta.
The pairwise()
or bufferCount(2, 1)
operators are looking like a good fit, but they start emitting only after buffer is filled, but I require this observable to start emitting from the first event of the underlying observable.
subject.someBufferingOperator()
.subscribe([previousValue, currentValue] => {
/** Do something */
})
;
On first emission the
previousValue
could be justnull
.
Is there some built-in operators that I can use to achieve the desired result?
pairwiselinkGroups pairs of consecutive emissions together and emits them as an array of two values.
Subjectlink. What is a Subject? An RxJS Subject is a special type of Observable that allows values to be multicasted to many Observers.
Note: pipe() is a function/method that is used to chain multiple RxJS operators while map() and filter() are operators that operate and transform the values of an Observable (sequence of values). They are similar to the map() and filter() methods of JavaScript arrays.
Actually, it was as easy as pairing pairwise()
with startWith()
operators:
subject .startWith(null) // emitting first empty value to fill-in the buffer .pairwise() .subscribe([previousValue, currentValue] => { if (null === previousValue) { console.log('Probably first emission...'); } }) ;
Here's the snippet for rxjs 6+
subject .pipe( startWith(undefined), pairwise() ) .subscribe(([previousValue, currentValue]) => { /** Do something */ });
The value in startWith()
should be undefined
because there is no value. Typically null
is defined as "we have a value and this value is empty".
Here's a simple operator:
function withPreviousItem<T>(): OperatorFunction<
T,
{
previous?: T;
current: T;
}
> {
return pipe(
startWith(undefined),
pairwise(),
map(([previous, current]) => ({
previous,
current: current!
}))
);
}
The nice thing about this is that the result has meaningful property names and correct types:
previous
is T | undefined
current
is T
(not T | null
)Stackblitz example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With