1

I am developing an application which doing network request using retrofit2 and rxjava2. I am doing it using MVVM approach which is in my RestInterface the result of the request returned in Flowable and in my repository I convert the Flowable into livedata so I can make the activity observe it in my viewmodel. But by doing this I got confuse on how to handle if there is no network where I ussually handle this in the rxJava side but since it's in the repository I can't do much thing about it.

Here is the code for the rest :

 @GET(NEWS_ARTICLE)
fun getArticlesFromSources(@Query("domains") source: String,
                           @Query("apiKey") apiKey: String = BuildConfig.NEWS_API_KEY):
        Flowable<NewsResponse>

The code for repository

fun getArticleFromSources(source: String) : LiveData<NewsResponse>{
    return LiveDataReactiveStreams.fromPublisher(newsRest.getArticlesFromSources(source)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io()))
}

and in my viewmodel :

private var mTriggerFetchData = MutableLiveData<String>()
private val article: LiveData<NewsResponse> = Transformations.switchMap(mTriggerFetchData){
    newsRepository.getArticleFromSources(it)
}
fun getArticle() = article

fun loadArticle(source: String?){
    mTriggerFetchData.value = source
}

and I observe it on my Activity :

getViewModel().getArticle().observe(this, Observer {newsResponse ->
        Log.v("test", newsResponse?.articles?.size.toString())
        articleList?.clear()
        newsResponse?.articles?.let { articleList?.addAll(it) }
        articleAdapter.notifyDataSetChanged()
    })

    getViewModel().loadArticle(sourceUrl)

As you can see, I was thinking to handle it in the activity but I still got confused about it. any help would be much appreciated. thanks!

mangkool
  • 316
  • 2
  • 18
  • https://stackoverflow.com/questions/52257744/how-to-retry-retrofit-call-on-http-errors-401-when-using-rxjava/52630766#52630766 In this answer is working code, which I used in different projects – Andrii Turkovskyi Oct 11 '18 at 11:59

1 Answers1

0

You can try add onErrorReturn() to the chain

fun getArticleFromSources(source: String) : LiveData<NewsResponse>{
    return LiveDataReactiveStreams.fromPublisher(newsRest.getArticlesFromSources(source)
        .observeOn(AndroidSchedulers.mainThread())
        .subscribeOn(Schedulers.io())
        .onErrorReturn((e: Throwable) -> {
            return e
        })
}

Or, rather than exposing just the NewsResponse through your LiveData object you can wrap the object and error into a wrapper class that can hold the error.

You can do something like this:

LiveDataReactiveStreams.fromPublisher(newsRest.getArticlesFromSources(source)
    .observeOn(AndroidSchedulers.mainThread())
    .subscribeOn(Schedulers.io()
    .map(Result::success)
    .onErrorReturn(Result::error))

Where Result class that holds either the error or result is something like this

class Result<T>(val data: T?, val error: Throwable?) {
    companion object {
        fun <T> success(data: T): Result<T> {
            return Result(data, null)
        }

        fun <T> error(error: Throwable): Result<T> {
            return Result(null, error)
        }
    }
}

You can then check if there's an error from the network