These are chat archives for ReactiveX/RxJava

30th
Aug 2016
gruns
@gruns
Aug 30 2016 21:44
How can two Observables be zipped and return a new Observable, not an Observable<Observable>? Observable.zip() returns an Observable of an Observable (i.g. Observable<Observable<Integer>>) when only the Observable (i.e. Observable<Integer>) is desired.
Dorus
@Dorus
Aug 30 2016 21:44
it shouldnt
can you show your code?
gruns
@gruns
Aug 30 2016 21:45
Sure. I'll rip out the unnecessary stuff and pbin it.
Dorus
@Dorus
Aug 30 2016 21:49
i can share some general ideas. For exmaple you should use flatMap no map to create the ziped observable.
source
  .flatMap(e =>
    Rx.Observable.zip(
      getFirst(e),
      getSecond(e),
      (first, second) => ({first, second}) // optional selector to collect results from inner functions
    ), (e, {first, second}) => ({e, first, second}) // optional selector to collect result and combine them with original.
  )
Dorus
@Dorus
Aug 30 2016 21:56
Are you trying to return an observable from the resultSelector?
I want loadInt() to return an Observable<Integer>, not Observable<Observable<Integer>>. Does that answer your question?
Dorus
@Dorus
Aug 30 2016 21:58
zip signature is zip(ob1 : Observable<S>, ob2 : Observable<T>, func : func2<S, T, R>) : Observable<R>
Notice func : func2<S, T, R> and you do func : func2<S, T, Observable<R>>
retrieveIntegerWithBoth should return an Integer not Observable<Integer>
gruns
@gruns
Aug 30 2016 21:59
Right. But retrieveIntegerWithBoth() needs to do network I/O and thus is asynchronous itself.
Dorus
@Dorus
Aug 30 2016 22:00
i would suggest you store the two items in a small data object and put flatMap as the next operator
gruns
@gruns
Aug 30 2016 22:00
Yuck.
Dorus
@Dorus
Aug 30 2016 22:00
That can be done outside the whole zip/flatmap
Why yuck?
gruns
@gruns
Aug 30 2016 22:02
That requires creating a new data type to be used only once, inside this function simply as a container.
Dorus
@Dorus
Aug 30 2016 22:02
private Observable<Integer> loadInt() {
    Observable<JsonObject> jsonObs = retrieveJSON();
    Observable<String> strObs = jsonObs.flatMap(
        new Func1<JsonObject, Observable<String>>() {
            @Override
            public Observable<String> call(JsonObject jsobj) {
                return retrieveString(jsobj);
            }
        });
    Observable<Integer> foo = Observable.zip(jsonObs, strObs, (json, str) -> new Object(){
      JsonObject json = json;
      String str = str;
    }).flatMap(e -> retrieveIntegerWithBoth(e.json, e.str));
}
gruns
@gruns
Aug 30 2016 22:03
What's the cleanest way to define <e> in the above example?
I'm not proficient in Java.
Dorus
@Dorus
Aug 30 2016 22:03
ooh doh
I ran into RxJava
sec lemme write this in Java not Js :)
@gruns Quick fix done
Mmm i forgot how bad this is for memory in Java. In C# it's meaningless because the Object will be gcd by the gen0 collection.
gruns
@gruns
Aug 30 2016 22:10
@Dorus Testing your example.
Dorus
@Dorus
Aug 30 2016 22:10
Quick google shows up Java probably deals with it rather similar. This object will never leave the initial heap. Beside it's a object with 2 references. Shouldnt be big. Hopefully the string and json object are gc'de just as fast.
gruns
@gruns
Aug 30 2016 23:12
@Dorus I was unable to migrate the anonymous Object() initialization in your example from lambdas to callbacks (Android doesn't support Java 8 lambdas).
Beyond that, though: huge thank you for your time and help. Sincerely.