Provides custom utility RxJS operators to simplify your codebase
npm install @lcsga/operators- bufferWhile now puts the value at the moment when the predicate returns false, as the first element of the incoming new buffer, since _while_ is an exclusive keyword. Also doing so mimics the takeWhile operator behavior that is also exclusive.
- In the predicate of bufferWhile, index now represents the i-th source emission that has happened since the subscription.
- bufferWhile now integrates the value at the moment when the predicate returns false, as the last element of the ongoing buffer, to mimic all of the already existing bufferXxx operators.
- debounceTimeMap: This operator extends the familly of of switchMap, mergeMap, concatMap and exhaustMap.
`ts`
debounceTimeMap
project: (value: T, index: number) => ObservableInput
dueTime: number
): OperatorFunction
| argument | type | description |
| --------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| project | (value: T, index: number) => ObservableInput | A function that, when applied to an item emitted by the source Observable, returns an Observable. |dueTime
| | number | The timeout duration in milliseconds, for the window of time required to wait for emission silence before emitting the most recent inner source value. |
Why do we need it?
Here is a use case you could easily encounter yourself:
You made a searchbar and you'd like to send a fetch request, while typing within it.
To avoid sending many requests at the same time (possibly causing an issue, receiving the first response after the second one for example) you would need to cancel the previous one by using a switchMap.
Another great thing you could and should do is, before sending any request, wait for a certain amount of time with no more input. To do so, you could use a debounceTime.
#### Example:
`html`
`ts
const input = document.querySelector
fromEvent
.pipe(
debounceTime(300),
switchMap(() => fromFetch('https://api.github.com/users/' + input.value, { selector: (res) => res.json() }))
)
.subscribe(console.log);
`
With those two operators, everything works as expected... or not!
What happens if your timing is bad and you press another set of key, with the first one pressed after 301ms, then the others under 300ms each?
=> You will never go through the switchMap for a second time, as you could expect, which means that the previous request won't be canceled!
Here comes the debounceTimeMap custom operator to the rescue!
As you could probably guess, it simply is a combination of a debounceTime and a switchMap.
#### Example:
`html`
`ts
const input = document.querySelector
fromEvent
.pipe(
debounceTimeMap(
() => fromFetch('https://api.github.com/users/' + input.value, { selector: (res) => res.json() }),
300
)
)
.subscribe(console.log);
`
In the example above, if you are unlucky and press another key a little after 300ms, after a first request has been sent already, the previous request will still be canceled and you won't face any unexpected behavior!
- debounceMap: It works exactly like debounceTimeMap but with a durationSelector instead of a dueTime!
`ts`
debounceMap
project: (value: T, index: number) => ObservableInput
durationSelector: (value: T) => ObservableInput
): OperatorFunction
| argument | type | description |
| ------------------ | ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| project | (value: T, index: number) => ObservableInput | A function that, when applied to an item emitted by the source Observable, returns an Observable. |durationSelector
| | (value: T) => ObservableInput | A function that receives a value from the source Observable, for computing the timeout duration for each source value, returned as an Observable or a Promise. |
#### Example:
`ts`
fromEvent
.pipe(
debounceMap(
() => fromFetch('https://api.github.com/users/' + input.value, { selector: (res) => res.json() }),
() => timer(300)
)
)
.subscribe(console.log);
- bufferWhile: Buffers the source Observable values until the predicates turns false.
`ts`
bufferWhile
| argument | type | description |
| ----------- | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| predicate | (value: T, index: number) => boolean | A function that evaluates each value emitted by the source Observable.false
Until the predicate returns the buffer is updated with each incomming values. When it returns false the buffer is emitted, with the last value, to the output Observable, before being reset for the next ongoing values.index
The parameter is the number i for the i-th source emission that has happened since the subscription, starting from the number 0. |inclusive
| | boolean | Optional. Default is false.predicate
When set to true the value that caused to return false will also be buffered. |
`ts
const source$ = of(1, 2, 3, 4, 5, 6);
const predicate = (nb) => nb !== 4;
// exclusive (default)
source$.pipe(bufferWhile(predicate)).subscribe(console.log);
// Outputs:
// [1, 2, 3]
// [4, 5, 6]
// inclusive
source$.pipe(bufferWhile(predicate, true)).subscribe(console.log);
// Outputs:
// [1, 2, 3, 4]
// [5, 6]
``