Managing Network State using RxJava

Managing Network State using RxJava hackernoon.com5 years ago in #Dev Love37

Originally published by Elye on July 12th 2017 We often use RxJava for fetching network result, but usually have it tell us either Success or Error. How nice if it could also tell us Loading and perhaps Empty (nothing loaded) state as well, so we don’t need to handle that logic separately, and have it communicate to the View the State result. Get started I believe the RxJava code below is no longer stranger to anyone who has coded a network call. service.fetchResult() .subscribeOn( .observeOn(AndroidSchedulers.mainThread()) .subscribe( { data -process(data) }, { error -report_error(error) } ) It’s supercool, as it helps one to put the network request to the background easily, and handle the result or result easily. Get greedier A lot of times, we want something more than just Data or Error. While waiting for the fetching, we want to show Loading State on the UI. If the result comes back as empty result, we want to show Empty State. In order to achieve that, we write more code surrounding the above Rx fetching code (within our presenter perhaps) to handle and update the UI accordingly. How nice if we could do that all in RxJava, as per illustrate in the diagram below. Get smarter Thinking about it, we could possibly do that. Instead of handling all the logic in our presenter, we have use a model that represent all the state. Here I defined it as below data class UiStateModel ( private val inProgress: Boolean = false, private val errorMessage: String? = null, private val dataModel: DataModel? = null ) { fun isLoading() = inProgress fun isError() = errorMessage != null fun isSuccess() = dataModel?.dataString?.isNotEmpty() ?: false && !isError() fun isEmpty() = !inProgress && errorMessage == null && !isSuccess() } We could setup the Model that store inProgress flag, errorMessage and data. Based on these info, the model could be used to check if it is in Loading, Error, Success or Empty state. To make this better, we could make the having some static class that instantiate UiStateModel per the state. companion object { fun loading() = UiStateModel(inProgress = true) fun success(dataModel: DataModel) = UiStateModel(dataModel = dataModel) fun error(error: Throwable) = UiStateModel(errorMessage = error.message) } Get linked So with this model now we have could represent the state, how we could combined to make use of it? Check out the code below that is used in the presenter. service.fetchResult() .map { data -UiStateModel.success(data) } .onErrorReturn { exception -UiStateModel.error(exception) } .startWith(UiStateModel.loading()) .subscribeOn( .observeOn(AndroidSchedulers.mainThread()) .subscribe({ uiState -when { uiState.isLoading() -view.isLoading() uiState.isError() -view.isError(uiState.getErrorMessage()) uiState.isSuccess() -view.isSuccess(uiState.getData()) uiState.isEmpty() -view.isEmpty() else -IllegalArgumentException(“Invalid Response”) } }) After fetching the result from the server, if it is successful, we convert it into a success UiStateModel. If it is error, we use onErrorReturn to convert it into an error UiStateModel. The nice bit here is, on start, we could use startWith to convert it to loading UiStateModel. We now have all the states specified, including empty State, which is handled internally within the UiStateModel to define it’s state. Get code I’ve made code example showing the flow in It shows all the states scenarios as below. Have fun! The example here is a very simplified example as per shared by Jake Wharton. Check it out further for more insights.  » Read More

Like to keep reading?

This article first appeared on If you'd like to keep reading, follow the white rabbit.

View Full Article

Leave a Reply