Short description of the issue:
Observable.combineLatest(Collection) with an empty Collection does not complete.
Expected outcome:
The Observable completes immediately.
What actually happens:
The Observable does not complete.
Self contained code example that reproduces the issue:
let disposeBag = DisposeBag()
Observable.combineLatest([Observable<String>]()) { $0 }
.subscribe(onCompleted: { print("completed!") })
.addDisposableTo(disposeBag)
// never prints "completed!"
RxSwift/RxCocoa/RxBlocking/RxTest version/commit
3.4.0
Platform/Environment
How easy is to reproduce? (chances of successful reproduce after running the self contained code)
Xcode version:
8.3.1
:warning: Fields below are optional for general issues or in case those questions aren't related to your issue, but filling them out will increase the chances of getting your issue resolved. :warning:
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)
Hi @scottrhoyt ,
yeah, I think we need to improve that behavior. I'm still not sure what is the best way to handle this. Completing the sequence seems the most probably candidate.
Were you using this to wait for aggregate network requests? What was the use case?
@kzaher similar.
My use case is waiting for an aggregation of local queries (in this case, querying a user's contacts). I filter some data (an array) before mapping it to an array of observables that I combine into an observable of an array. The completion of this combined observable has a side effect of stopping a loading indicator. I noticed that when the filtering process produced an empty array, the resulting combined observable would never complete and my loading indicator would never stop.
It was fairly simple to workaround by mapping to an empty observable when the array of observables is empty, but the behavior was counterintuitive to me.
@scottrhoyt yeah, agreed. We'll fix this somehow.
We have the same problem with zip operator. Combine latest is more straightforward to solve, but we'll figure something out. I would like to investigate first how other implementations are behaving in these cases.
I occurred this situation when I use zip , hope it will fix soon
Thanks @kzaher. Let me know if you need any additional feedback.
Fix for this is pushed in develop branch. We'll release this in a couple of days.
I tried to use Observable.empty() in Zip operator. The completion block wouldn't execute in that case. I tried a sort of hack
Observable<Response>.empty().ifEmpty(default: Response(statusCode: 0,data: Data.cs_emptyValue()))
My expected value of Observable is Response. (Maya Response object) I gave it empty data and status code 0 with Observable type
@kzaher not sure if this is the correct approach, but this looks like a solution in my case. As I have dynamic observables to be called.
I run into this issue while testing view models using RxCocoa. In my case I have something like
let search = Variable("")
search.flatMapLatest { query -> Observable<Result> in
guard !query.isEmpty else {
return .empty()
}
return ... //Some observable
Most helpful comment
Fix for this is pushed in develop branch. We'll release this in a couple of days.