Short description of the issue:
When flatmapping to Completable, the subscribe block is not called, but the subscription is triggered.
Expected outcome:
Subscribe block is called.
Self contained code example that reproduces the issue:
self.doneButton.rx.tap
.flatMap {
// doing an API call
// returns Completable
model.update().do(onCompleted: { log.debug("Completed") }) // api call is actually executed and the message is logged
}
.subscribe(onCompleted: {
log.debug("Sub completed") // never called
self.unwind() // this never called
})
.disposed(by: self.disposeBag)
RxSwift/RxCocoa/RxBlocking/RxTest version/commit
4.5.0
Platform/Environment
How easy is to reproduce? (chances of successful reproduce after running the self contained code)
Xcode version:
Xcode 10.2
Installation method:
I have multiple versions of Xcode installed:
(so we can know if this is a potential cause of your issue)
Level of RxSwift knowledge:
(this is so we can understand your level of knowledge
and formulate the response in an appropriate manner)
Completion inside a flatMap doesn鈥檛 complete the outer sequence.
@freak4pc So this is by design then? It's super-unobvious to me. I have some API calls that I don't care to get the result data for and they are all Completable. But I certainly would want to have outer sequence react to "completed" events... Just like in my example - a user presses a button, we make a call and then just close the page after the call is completed.
This actually works just fine for me
func c() -> Completable {
return Completable.create { c in
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
c(.completed)
}
return Disposables.create()
}
}
_ = Observable
.just(())
.flatMapLatest { c() }
.subscribe(onCompleted: { print("yo") })
@freak4pc Tried your example directly in my codebase - worked. Replaced only the Observable part - to button.rx.tap - stopped working. But the same tap even works fine when flat mapping Single.
Yeah - think about it, if a flatMap completion would terminate the outer stream, it would mean that no more button taps would be registered in your stream, which don't really make sense.
As I mentioned, this is planned behavior. My example above worked because the "just" stream itself terminated immediatley.
Thanks for the explanation, I understood what you meant. Still, in my case, termination of tap evens would make sense and was exactly what I wanted. The idea was exactly that - do something and leave the page, so I wouldn鈥檛 care for any tap evens after the completed in the inner sequence.
You can do a take(1) on the button tap in that case.
Most helpful comment
Yeah - think about it, if a flatMap completion would terminate the outer stream, it would mean that no more button taps would be registered in your stream, which don't really make sense.
As I mentioned, this is planned behavior. My example above worked because the "just" stream itself terminated immediatley.