Serg Burlaka
Serg Burlaka

Reputation: 2496

Get remote data or get local via rxJava 2

I has very simple task to send request for remote data. But need to handle my request and get local on remote error. Functionality way like a mathematics has many ways to solve problem.

So first ost simple сomes to mind to do this:

val remote = remotePurchase
                .getAvailableUsersMaxCount()
                .subscribe({},{
                   //on failed            
                  getLocal()
        })

But i thing it is rx beginner guy also it is callback in callback bad way.

Also i think to do this:

  override fun getActualUsersMaxCount(): Observable<Int> {
            return remotePurchase
                    .getAvailableUsersMaxCount()

                    .flatMap {
                        updateUsersCount(it)
                    }
                    .onErrorReturn {
                        userLocal.getById(PrefProvider.userId).map {
                            it.chatUsersCount?:0
                        }.blockingFirst()
                    }
        }

Bute some times handle:

Caused by: rx.exceptions.CompositeException: 2 exceptions occurred.

Like this github.com/ReactiveX/RxJava/issues/3679

Then i known about using toBlocking is not best idea. See post here.

After some time i decided mutch better this:

 override fun getActualUsersMaxCount(): Observable<Int> {

    val remote = remotePurchase
            .getAvailableUsersMaxCount()
            .flatMap {
                updateUsersCount(it)
            }.onErrorReturn { -1 }

    return zip(remote, userLocal.getById(PrefProvider.userId).map {
        it.chatUsersCount ?: 0
    }, { remoteCount, localCount ->

        if(remoteCount!= -1) remoteCount else localCount

    })
}

So now i almost control situation. If i got error from network I can check it and receive local result

But what variation better as you think? May be there is more simplify decision?

Upvotes: 0

Views: 348

Answers (1)

iagreen
iagreen

Reputation: 31996

You can use onErrorResumeNext to avoid the blockingFirst call in your second solution. This makes it the better solution, in my opinion. Not sure what two exceptions, you are talking about. Can give some more context on what they are, as I don't see the issue.

override fun getActualUsersMaxCount(): Observable<Int> {
    return remotePurchase
        .getAvailableUsersMaxCount()
        .flatMap {
             updateUsersCount(it)
        }
        .onErrorResumeNext(
                 userLocal.getById(PrefProvider.userId).map {
                 it.chatUsersCount?:0
             })
}

Upvotes: 1

Related Questions