LR89 LR89 -4 years ago 206
Java Question

Filter RxJava Observable with other Observable

I'm using RxAndroid 2.0.1 with RxJava 2.0.6.

I have two observables: one returns

Maybe<MyObject>
based on some String (ID). When the optional object is returned, I have to call the second one that takes the MyObject instance and returns
Single<Boolean>
if object meets some conditions. Then I can do some further operations with the object instance.

My current implementation is as follows:

objectDAO.getById(objectId)
.subscribe(
myObject -> checkCondition(myObject),
throwable -> /* Fallback */,
() -> /* Fallback */
);

private void checkCondition(final MyObject myObject) {
otherDAO.checkCondition(myObject)
.subscribe(
isTrue -> {
if (isTrue) {
// yay! now I can do what I need with myObject instance
} else {
/* Fallback */
}
},
throwable -> /* Fallback */
);
}


Now I'm wondering how could I simplify my code. My ideas:


  1. Try to use
    zip
    - I can't because second Observable can't be subscribed until the first one returns the MyObject

  2. Try to use
    filter
    - Now the issue is that I need to use blocking get to call second observable. It will propably work, but looks like a code smell:

    objectDAO.getById(objectId)
    .filter(myObject ->
    otherDAO.checkCondition(myObject).blockingGet()
    )
    .subscribe(
    myObject -> checkCondition(myObject),
    throwable -> /* Fallback */,
    () -> /* Fallback */
    );

  3. Try to use
    flatMap
    - The second observable returns Boolean while I need to return the original object. Because of that I need to mape a code snippet with
    blockingGet
    and return original object or
    Maybe.empty()



Any suggestions how to do it in such a way that the code is "clean" (it's smaller and it's still clear what's happening inside)?

Answer Source

One thing you could do:

objectDAO.getById(objectId)
    .flatMapSingle(myObject -> otherDAO
        .checkCondition(myObject)
        .map(isTrue -> Pair.create(myObject, isTrue))
    )

Then you have an Observable<Pair<MyObject, Boolean>> and can proceed however you want: subscribe directly and check the Boolean there, filter by the Boolean value, etc.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download