简体   繁体   中英

how to emit error then emit the cached data using RxJava?

I am using RxJava in a MVP solution and I want to achieve this scenario:

  • try to get the server data and if its successful populate the view using server data

  • if its unsuccessful for any reason (no internet - server unreachable - server internal error) show the appropriate message but also populate view with the cached data .

constraints:

  • I don't wanna use any extra callback (RX can do it all)

  • I don't wanna access local repo directly from Presenter

what I tried:

in my Repo:

    override fun getRepos(userName: String, page: Int, pageSize: Int):Observable<List<Repo>> {

 return githubRemoteService.getReposList(userName, page, pageSize)
                .subscribeOn(schedulersProvider.ioThread())
                .flatMap { repos ->
                    val mappedRepos = remoteResponseMapper.mapRepoResponse(repos)
                    githubLocalService.saveRepos(mappedRepos)
                    Observable.just(mappedRepos)
                }
 .onErrorResumeNext(Observable.just(githubLocalService.getReposList(userName, page, pageSize)))
               .observeOn(schedulersProvider.mainThread())

    }

in my presenter:

githubInteractor.getRepos(userName, page, pageSize).subscribe(
            { repos ->
                 showReposInView(repos)
            },
            { error ->
                digestAndShowErrorInView(error)  //the problem is here - no error will be present here
            })

as we know when I use onErrorResumeNext , the observable source changes but the error will never be emitted .

how can I emit the error first and then emit local repo data ?

if it cant be done like this, how can I change my scenario to get the same scenario ?

You can't use onError and continue the stream. onError means a critical error occurred and the Observable ends. You can't use it.

There is a simple solution. You can wrap your result in a structure that indicates error/data. Eg

sealed class MyData
data class Success(val data: List<Repo>) : MyData
data class Error(val t: Throwable): MyData

The you can map the successful API response to Success and in case of error (in onErrorResumeNext ) you can create an Error class and use concat to continue with the local repo list.

This way you get both errors and success in onNext and you don't break the chain.

In onNext you can use when and handle error/success appropriately.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM