Reputation: 948
I have an observable
that looks like this:
func getParameters() -> Single<[ParameterModel]?> {
do {
loading.accept(allParameters.isEmpty)
return try parameterService.getParameters()
.do(onSuccess: { [weak self] parameters in
self?.loading.accept(false)
self?.content.accept(parameters?.compactMap { $0 }
.compactMap { TechnicianParameterTableViewCellViewModel(parameter: $0) } ?? [])
})
} catch { return Single.error(error) }
}
The important part is where it compactMaps
into a cell
. This works as expected. But I also have another observable that looks like this:
func getSingleOrDoubleDoor() -> Single<SingleOrDoubleDoor?> { //SingleOrDoubleDoor is an enum
do {
return try parameterService.getSingleOrDoubleDoor()
} catch {
return Single.error(error)
}
}
Now, I would like to sort of merge getSingleOrDoubleDoor()
into getParameters()
so that I can access the values of both observables
in onSuccess
. I want to use the result sort of like this:
.compactMap { TechnicianParameterTableViewCellViewModel(parameter: $0, isSingleOrDouble: $1) } ?? [])
Not being an expert on Rx
I still assume that this is done using .flatMap{}
. Sort of like:
...return try parameterService.getParameters().flatMap { _ in getSingleOrDoubleDoor() }...
But this gives me an error:
Cannot convert value of type '([ParameterModel]?) -> Single<SingleOrDoubleDoor?>' (aka '(Optional<Array>) -> PrimitiveSequence<SingleTrait, Optional>') to expected argument type '([ParameterModel]?) throws -> PrimitiveSequence<SingleTrait, [ParameterModel]?>'
Tried changing the return expression but it still wouldn't take. Not sure how to make this happen.
Upvotes: 1
Views: 476
Reputation: 5203
Since your methods don't accept parameters, I'll assume they don't depend on each other. If so, you should use the zip
method like this:
Single
.zip(getParameters(), getSingleOrDoubleDoor())
.compactMap { TechnicianParameterTableViewCellViewModel(parameter: $0, isSingleOrDouble: $1) } ?? [])
The zip method will trigger the compactMap when both methods return a value. Flatmap
has a different purpose, it is usually used when we need to call methods sequentially, meaning the next call needs data from the previous one.
Upvotes: 1