Closed robertofrontado closed 6 years ago
Hi @robertofrontado ,
I've read http://blog.danlew.net/2015/03/02/dont-break-the-chain/
I don't think we have the same problem in Swift, you can just define an extension on ObservableType
extension ObservableType {
public func applyOperators() -> Observable<E> {
return self.subscribeOn(backgroundScheduler)
.observeOn(MainScheduler.instance)
}
}
Thanks @kzaher,
Yeah, I was reading that blog too, and I just wanted to know if there was already that function, so I'm going to do that
@kzaher I love the clarity Extension functions bring into the chain. But I have a problem when trying to mock those for Unit testing purposes, wich would be possible with ObservableTransformer and the compose() Method. As of I know, it‘s not possible right now To mock an Extension function. Pls correct me if I‘m wrong!
@vander2675 I think these two approaches are equivalent in power
extension ObservableType {
public func applyOperators(scheduler: SchedulerType) -> Observable<E> {
return self.subscribeOn(scheduler)
.observeOn(scheduler)
}
}
I think RxJS is going this way with pipe
operator also. It would be great if RxJs and RxJava would unify compose
and pipe
into some name.
As far as I'm concerned, this should be trivial to implement, and wouldn't our code base too much, so maybe we should revise this.
@kzaher As far as i understand is the pipe Operator also implemented to not pull the whole operators dependencies into the project. And the Syntax is different to the compose from RxJava. So you share my opinion about missing testability from Extensions?
I allready tried out an approach, wich I can share if you like?
As far as I can tell none of these operators is introduced because of testability and dependency injection, that is just a consequence of the fact they allow you to define "operators" in certain scope.
Sorry I don‘t really understand what you mean. Do you mean the Operators like map, filter are not introduced because of Testability or DI? I don‘t want to introduce compose() with ObservableTransformers because of testability. Just to make it possible, wich is not with Extension functions. All other Operators are testable. Or did I missunderstand you?
I mean that neither of the operators, including pipe
and compose
are introduced because of testability.
Just to make it possible, wich is not with Extension functions. All other Operators are testable.
Again, you can make testable operators yourself. You need to expose dependencies as arguments.
extension ObservableType {
public func applyOperators(scheduler: SchedulerType) -> Observable<E> {
return self.subscribeOn(scheduler)
.observeOn(scheduler)
}
}
... or one can define their own compose
operator and use anonymous lambdas.
Testability of the operators ~ ability to inject dependencies
compose
and pipe
~ ability to scope operators (anonymous transformer lambdas) per specific regions (files, classes, structs, enums, functions ....)
For those curious here is my implementation:
protocol Transformer {
associatedtype Upstream
associatedtype Downstream
func apply(_ events: Observable<Upstream>) -> Observable<Downstream>
}
extension ObservableType {
func compose<T: Transformer>(_ transformer: T) -> Observable<T.Downstream> where E == T.Upstream {
return transformer.apply(self.asObservable())
}
}
Now you can create your own Transformer
types and compose them easily. This also allows you to keep types abstract so you can mock your own transformers for unit testing
Another way is a functional approach, instead of a OO approach:
extension ObservableType {
func compose<R>(_ transformer: (Observable<E>) -> Observable<R>) -> Observable<R> {
return transformer(self.asObservable())
}
}
No need for the protocol Transformer.
You use it like that:
func schedulingStrategy<T>(_ observable: Observable<T>) -> Observable<T> {
return observable
.subscribeOn(scheduler)
.observeOn(scheduler)
}
someObservable
.compose(schedulingStrategy)
.subscribe()
You will need some sort of Factory to generate those func so that they capture external var like scheduler.
@malaba, yes, this is the form that has a more Swift like interface.
Rxjs also has pipe that is quite simular, although pipe is more powerful.
I was actually talking about this operator the other day. I don't think we necessarily need this in RxSwift core, but apply
from RxSwiftExt does exactly what you're looking for, to the best of my understanding: https://github.com/RxSwiftCommunity/RxSwiftExt#apply
Closing this issue for now as its been too long standing and there have already been several implementation ideas here for people who'd like to add to their codebase.
Please let me know if you have additional questions regarding this or if you feel this needs to be re-opened.
Thanks!
Hello guys,
I want to know if there is an equivalent of compose() from RxJava in RxSwift?, I couldn't find anything
Reference: http://reactivex.io/RxJava/javadoc/rx/Observable.html#compose(rx.Observable.Transformer)