[feat] `rxjs/concat` : pass last value of previous Observable to the next one
See original GitHub issueProblem
The “master” subscriber needs values emitted by outer observable “as they happen”; and when it completes, should seamlessly switch over to the next observable in the chain. (the next in the chain also needs the last emitted value of prev/outer obs to compute its own result)
Tried and failed
I tried using concat from rxjs but that doesn’t pass the last value emitted by previous observable to the next one in chain.
I tried using concatMap from rxjs/operators but that “holds up” the emission until outer and inner observables are done. (I reckon its only good for preserving the order)
Solution
type ObservableGenerator<T> = Observable<T> | ((v: T) => Observable<T>)
function chain<T>(seed: Observable<T>, ...obsGenerators: Array<ObservableGenerator<T>>) {
return new Observable<T>(masterSubscriber => {
let lastValueFromPrev: T
let childSubscription: Subscription
const switchTo = (obs: Observable<T>) => {
childSubscription = obs.subscribe({
next: v => {
lastValueFromPrev = v
masterSubscriber.next(v)
},
error: masterSubscriber.error,
complete: () => {
childSubscription.unsubscribe()
const next = obsGenerators.shift()
if(!next) {
masterSubscriber.complete()
} else {
switchTo(typeof next === 'function' ? next(lastValueFromPrev) : next)
}
}
})
}
switchTo(seed)
return () => {
childSubscription.unsubscribe()
}
})
}
And then it can be used like so:
EDIT: Example removed.
Much better example below: https://github.com/ReactiveX/rxjs/issues/4711#issuecomment-483080247
Issue Analytics
- State:
- Created 4 years ago
- Comments:10 (3 by maintainers)
Top Results From Across the Web
RxJS - concat last emitted value with previous values
The concat operator subscribes to the second Observable b$ only after $a completed. However at the time $a completes the value 3 was...
Read more >concat - RxJS Reference | indepth.dev
When a new value arrives from a source observable, pass it down to an observer; Once this source observable completes, subscribe to the...
Read more >RxJS - concat last emitted value with previous values-rx.js
The concat operator subscribes to the second Observable b$ only after $a completed. However at the time $a completes the value 3 was...
Read more >concat - RxJS
concat<T, A extends readonly, unknown>(). Parameters. There are no parameters. Code licensed under an Apache-2.0 License. Documentation licensed under CC BY ...
Read more >Concat operator - ReactiveX
The Concat operator concatenates the output of multiple Observables so that they ... Observable that you pass to it until the previous Observable...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found

Here’s a much better example:
Imagine we have an asynchronous image rendering pipeline. There are multiple filters/shaders in the said pipeline and each of them takes
ImageDatafrom the preceding filter/shader, transforms it, and passes it on to the next one.Here’s the tricky part; the user must see the process as it happens; live. Instead of just the final output. That way he can cancel the render midway if he notices some rendering artifacts during the render.
Each filter/shader can only process 128 pixel block at a time. Every
requestAnimationFramecycle it’ll.next(...)what it has computed so far, and then on to the next 128 pixel block. Accumulate, emit and repeat..complete()when it is done.Here’s what it’ll look like:
Illustration above is not same as:
Here
imageData$won’t receive anything until entire pipeline is.complete(). We want live output.Makes sense. Thanks for the explanation.