Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)?

like image 932
LR89 Avatar asked Mar 22 '17 12:03

LR89


1 Answers

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.

like image 52
david.mihola Avatar answered Sep 25 '22 09:09

david.mihola