I have a problem with writing the .zip Observable in Kotlin using Android Studio 3.0 IDE.
Here is my code:
internal var updateStringEventsSubject = PublishSubject.create<String>()
internal var updateIntEventsSubject = PublishSubject.create<Int>()
internal var triggerSave = PublishSubject.create<Boolean>()
internal var triggerStopAndSave = PublishSubject.create<Boolean>()
internal var normalSaveTrigger = triggerSave.debounce(30, TimeUnit.SECONDS)
internal var trigger = Observable.merge(normalSaveTrigger, triggerStopAndSave)
private fun saveEvents(
strings: List<String>,
integers: List<Int>,
someBoolean: Boolean): Boolean {
return true //doesn't matter for now
}
fun temp() {
Observable.zip<List<String>, List<Int>, Boolean, Boolean>(updateStringEventsSubject.buffer(trigger),
updateIntEventsSubject.buffer(trigger),
trigger, { strings: List<String>, integers: List<Int>, someBoolean: Boolean -> saveEvents(strings, integers, someBoolean) })
.subscribe()
}
However, my IDE(Android Studio 3.0 RC2) underlines the .zip operator and says:
None of the following functions can be called with the arguments supplied. zip(((observer: Observer!>) → Unit)!, ((observer: Observer!>) → Unit)!, ((observer: Observer) → Unit)!, ((t1: List, t2: List, t3: Boolean) → Boolean)!) where T1 = List, T2 = List, T3 = Boolean, R = Boolean for fun zip(source1: ((observer: Observer) → Unit)!, source2: ((observer: Observer) → Unit)!, source3: ((observer: Observer) → Unit)!, zipper: ((t1: T1, t2: T2, t3: T3) → R)!): Observable! defined in io.reactivex.Observable zip(((observer: Observer!>) → Unit)!, ((observer: Observer!>) → Unit)!, ((t1: List, t2: List) → Boolean)!, Boolean) where T1 = List, T2 = List, R = Boolean for fun zip(source1: ((observer: Observer) → Unit)!, source2: ((observer: Observer) → Unit)!, zipper: ((t1: T1, t2: T2) → R)!, delayError: Boolean): Observable! defined in io.reactivex.Observable zip(ObservableSource!>!, ObservableSource!>!, ObservableSource!, io.reactivex.functions.Function3!, in List!, in Boolean!, out Boolean!>!) where T1 = List, T2 = List, T3 = Boolean, R = Boolean for fun zip(source1: ObservableSource!, source2: ObservableSource!, source3: ObservableSource!, zipper: Function3!): Observable! defined in io.reactivex.Observable zip(ObservableSource!>!, ObservableSource!>!, BiFunction!, in List!, out Boolean!>!, Boolean) where T1 = List, T2 = List, R = Boolean for fun zip(source1: ObservableSource!, source2: ObservableSource!, zipper: BiFunction!, delayError: Boolean): Observable! defined in io.reactivex.Observable
How to make it work with Kotlin?
For some reason using RxJava 1.1.7 it considers explicitly specifying the type of zipper argument as Func3 a redundant SAM-constructor (which it is) and allows you to replace it with a lambda. However, using RxJava 2.1.5 the type changes to Function3 and it no longer recognises it as an interface with a single abstract method (which it still is). I'm not sure why that is.
Regardless, specifying the type of the zipper function will do the trick:
import io.reactivex.functions.Function3
...
fun temp() {
Observable.zip<List<String>, List<Int>, Boolean, Boolean>(updateStringEventsSubject.buffer(trigger),
updateIntEventsSubject.buffer(trigger),
trigger, Function3 { strings, integers, someBoolean -> saveEvents(strings, integers, someBoolean) } )
.subscribe()
}
Note: I managed to get it to work without explicitly specifying the type arguments for Function3
. It may depend on which version of Kotlin or RxJava you're using as to whether it can infer the types. If not you can always be more explicit:
Function3<List<String>, List<Int>, Boolean, Boolean> { ... }
Edit: There's an even easier way: Use io.reactivex.rxkotlin.Observables
instead. It's an inline function that does the ugly type declaration under the hood for us. Then you can just do this:
import io.reactivex.rxkotlin.Observables
...
Observables.zip(updateStringEventsSubject.buffer(trigger),
updateIntEventsSubject.buffer(trigger),
trigger,
::saveEvents)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With