Aks4125
Aks4125

Reputation: 5720

RxJava observe multiple observers in single subscriber

Code

Author author = baseRealm.where(Author.class).equalTo("id", mId).findFirst();

public boolean checkGlobalSyncStatus(Author author, List<Books> mBooks) {

    final boolean[] isJobSynchronized = {false};

    Observable.fromIterable(mBooks)
            .filter(Books::isChanged)
            .doOnNext(book -> isJobSynchronized[0] = true)
            .just(author)
            .flatMapIterable(Author::getAllBooks)
            .filter(MyBook::isChanged)
            .doOnNext(mBook -> isJobSynchronized[0] = true)
            .just(author)
            .flatMapIterable(Author::getAllWriters)
            .filter(Writers::isChanged)
            .doOnNext(jobPage -> isJobSynchronized[0] = true)
            .subscribe();

    return isJobSynchronized[0];
}

Problem

fromIterable(mBooks) is called from static-reference Observable BUT just(author) is called from instance-reference.

I only want to get this operation done in single query. I can make different observable for each and perform desired operation but that would be lengthy.

Why?

By doing so, SonarQube is giving me unsuccessful check and forcing me to remove instance-reference.

Any alternatives will be appreciated.


Lint analysis

Upvotes: 1

Views: 1700

Answers (2)

akarnokd
akarnokd

Reputation: 70017

There is no reason to use RxJava here, however, the proper combination of operators would be as follows:

Author author = baseRealm.where(Author.class).equalTo("id", mId).findFirst();

public boolean checkGlobalSyncStatus(Author author, List<Books> mBooks) {

    return Single.concat(
                Observable.fromIterable(mBooks)
                .any(Books::isChanged)
                , // ---------------------------------------------
                Observable.fromIterable(author.getAllBooks)
                .any(MyBook::isChanged)
                , // ---------------------------------------------
                Observable.fromIterable(author.getAllWriters)
                .any(Writers::isChanged)
           )
           .any(bool -> bool)
           .blockingGet();
}

Upvotes: 0

Bob Dalgleish
Bob Dalgleish

Reputation: 8227

You are trying to use just() as an operator when it is really an observable. It looks like your intention is to use the passed in author to make a series of queries, and then check that any of the books associated with the author have "changed".

Additionally, you are trying to return a boolean value that likely has not been set by the time the return occurs. You may need to block and wait for the observer chain to finish if you want the value. More likely, you want the observer chain to finish if any book has changed.

Additionally, the series of steps where you set the flag to true come down to setting the flag to true the first time.

Instead of just(), use map() to rebind the original author into the observer chain. Use the toBlocking() operator to make the process synchronous.

Observable.fromIterable(mBooks)
        .filter(Books::isChanged)
        .toBlocking()
        .subscribe( ignored -> isJobSynchronized[0] = true );

return isJobSynchronized[0];

Since the (presumably) asynchronous queries are no longer necessary to compute the value, remove RxJava:

return mBooks.stream()
         .filter(Books::isChanged)
         .anyMatch();

Upvotes: 1

Related Questions