Hey,
the addition of flatMapSingle/flatMapCompletable made the usage of Single and Completable way nicer in RxJava 2.
Do you consider adding switchMapSingle/switchMapCompletable to RxJava 2 as well?
Cheers
You mean 1.x? I have no plans for that and I don't want to keep 1.x alive for too long. I'd like to stop enhancing 1.x in 6 months and enter it into a bugfix-only mode. Otherwise 3rd party libraries may delay their upgrade way longer.
He wants switchMapSingle and switchMapCompletable for RxJava 2 just like there is flatMapSingle and flatMapCompletable
@vanniktech exactly
Ah right. No plans for extending any other xMap operator
But then concatMap also needs the variants in order to be consistent. To be honest I forgot about those when proposing flatMapSingle / flatMapCompletable / flatMapMaybe initially - #4667
And then there's also Maybe. Plus Observable and Flowable are able of mapping so it's easily another 12 methods.
If it is not on the roadmap because you don't want to add any more xMap operators, then I understand.
But if it is due to lack of the time, would you consider accepting contributions on the topic?
Sure, but these operators are not easy.
Yes, I know, those are one of the hardest.
Still, I will at least have a look and see if I can deliver a PR.
Cheers!
Any progress on this?
I'm happy to have a look at this one if @tomaszpolanski doesn't have time at the moment.
@davidmoten It would be great! My available time now is pretty limited.
So the list of new operators is quite big. Currently:
I imagine we can add support for all of these operators straight away using composition and write dedicated operators later one by one. An example would be Observable.switchMapSingle:
public final <R> Observable<R> switchMapSingle(
final Function<? super T, ? extends SingleSource<? extends R>> mapper) {
Function<? super T, Observable<R>> mapper2 = t ->
{
SingleSource<? extends R> source = mapper.apply(t);
Single<? extends R> single;
if (source instanceof Single) {
single = (Single<? extends R>) source;
} else {
single = Single.unsafeCreate(source);
}
return (Observable<R>) single.toObservable();
};
return switchMap(mapper2, bufferSize());
}
This is just to demo the idea, I wouldn't use an anonymous class and lambdas are just used for readability.
@akarnokd any interest in this?
I imagine we can add support for all of these operators straight away using composition and write dedicated operators later one by one.
Indeed.
An example would be
If you do this, there is an unwritten guideline that the main base types should have no (anonymous) inner classes. It helped me a lot before not having to deal with Flowable$1$2 and similar entries. The go-to place for these are in io.reactivex.internal.operators.flowable.FlowableInternalHelper and its respective variants.
any interest in this?
I'm more interested in the direct implementations but at least the overall usefullness of the API extension could be vetted.
If you do this, there is an unwritten guideline that the main base types should have no (anonymous) inner classes. It helped me a lot before not having to deal with Flowable$1$2 and similar entries. The go-to place for these are in io.reactivex.internal.operators.flowable.FlowableInternalHelper and its respective variants.
Yep no problems. I've appreciated consistent naming of non-anon classes inside operators for debugging purposes and code searches too.
I'm more interested in the direct implementations but at least the overall usefullness of the API extension could be vetted.
Sure. I'll proceed with PRs with unit tests for the new operators and I'm happy to have a stab at dedicated operators after that.
What is expected behaviour for Observable.switchMapMaybe and Observable.switchMapCompletable? I can try to take care of it but I am not convinced what that method should return.
In the mean time, would it be correct to assume that an acceptable workaround for this is as follows?: .toObservable()
upstream.concatMap {
someObservable().collect{...}.toObservable()
}
@feresr
Probably yes, at this moment in few places inside my code i have this type of stucture. It is very weird and uncessesery code but it is understandable.
@akarnokd
What do you think about method switchMapCompletable which emit Object or maybe some enum? On the other hand we can we can swallow information about stream and do not emit anything.
@marcinsus I don't fully understand your question. Use switchMapCompletable().andThen(Single) to emit something after the switch completed.
The problem he talks about is that switchMapCompletable does not exist.
switchMapSingle returns an Observable of the Single type.
So technically switchMapCompletable should return Void. (Which it can't, because that has no instance.) So he asks if the signature should rather expose some enum Nothing or just an Object
An Observable.switchMapCompletable should return Completable.
You are right as flatMapCompletable returns a Completable.
But now I find it weird that
Observable.flatMapSingle<T>returns an Observable<T>
but
Observable.flatMapCompletable returns an Completable.
A stream of 5 elements flatMap'd to a stream of a single element still results in a stream of 5 elements.
I'm working on implementing concatMapCompletable across the reactive types.
I'm wondering if the library should also have implementations of
concatMapDelayErrorCompletable, concatMapEagerCompletable, concatMapEagerDelayErrorCompletable?
concatMapEagerCompletable is indistinguishable from flatMapCompletable because all sources run concurrently and their only output is a terminal event; no items have to be buffered until their turn. Also the maxConcurrency == 1 gets you concatMapCompletable behavior.
Ahh yes that makes sense.
So is there any reason to implement concatMapCompletable at all? If so do you want it to just use flatMapCompletable() internally or should there be a new direct implementation (what I've been working on)?
Actually, Observable.flatMapCompletable doesn't have maxConcurrency overload thus there might be a reason to implement concatMapCompletable.
Ok I'll keep at it then
https://github.com/ReactiveX/RxJava/issues/4853#issuecomment-281541715
Did anything ever come of this?
So there are plans to implement the other operators, but not in any particular timeframe?
The listed operators can simply expressed with the existing default operators and toObservable/toFlowable in the lambda parameters. Unfortunately, very few people could or are willing to write them in an optimized and inlined fashion - which would add more value to the library than a simple lambda-rewriting function. Imagine, you have to write a proper javadoc with a marble diargram and several hundred lines of unit tests to validate and cover a new operator with some 3 lines of code. Kotlin's extension methods really shine in allowing interested parties to define such convenience functions locally to their project and not boomeranging such features through the RxJava library. The issue is left open in case somebody really wants to take the time and effort to contribute but as the core developer, I'm not particularly interested myself in tackling these types of operators.
Closing via #5870, #5871, #5872, #5873, #5875.
Most helpful comment
But then
concatMapalso needs the variants in order to be consistent. To be honest I forgot about those when proposingflatMapSingle / flatMapCompletable / flatMapMaybeinitially - #4667And then there's also
Maybe. PlusObservableandFlowableare able of mapping so it's easily another 12 methods.