RxJava Tidbits #1: Use flatMap() and retain original source value

Howdy!

I decided to share some tips & tricks and solutions to common, real-world problems I have encountered whilst working with RxJava (on Android), hoping that it will save others some time and effort.


Let’s jump right into Tidbit #1:

Assuming you are working with the following Observable, how do you get access to the initial String value (“foo”) further down in the chain?

Observable.just("foo")
.flatMap(new Func1<String, Observable<Integer>>() {
@Override
public Observable<Integer> call(String s) {
return Observable.range(1, 5);
}
})
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer i) {
// how do you access "foo" String?
System.out.println("Result: " + i);
}
});

It turns out there is an overloaded method of flatMap() which takes a Func2 as its 2nd parameter and returns an Observable which emits the results of a specified function to the pair of values emitted by the source Observable and the flatMap()’s Observable itself:

public final <U,R> Observable<R> flatMap(
Func1<? super T, ? extends Observable<? extends U>> collectionSelector,
Func2<? super T, ? super U, ? extends R> resultSelector
)
Observable.flatMap() with result selector

So here is the updated snippet:

Observable.just("foo")
.flatMap(new Func1<String, Observable<Integer>>() {
@Override
public Observable<Integer> call(String foo) {
return Observable.range(1, 5);
}
}, new Func2<String, Integer, Pair<Integer, String>>() {
@Override
public Pair<Integer, String> call(String s, Integer i) {
return new Pair<>(i, s);
}
})
.subscribe(new Action1<Pair<Integer, String>>() {
@Override
public void call(Pair<Integer, String> pair) {
System.out.println("Result: " + pair.first + " Foo: " + pair.second);
}
});

Note that I am using a simple Pair (tuple) as a container object to quickly wrap and unwrap the two objects.

Show your support

Clapping shows how much you appreciated Jens Driller’s story.