Reputation: 413
When the Retrofit Call does not succeed ( for example because no Internet), is called as expected the RXJava Callback onError
, where I have a Snackbar
with a setAction()
Listener indicated with an intuitive String "Retry" where I should pass a command to start again the network call.
I could restart the class where I am inside calling it NameActivity()
, but this look terrible.Which command I can pass inside the Snackbar
listener to restart the below code?
MyViewModel!!.getPost("132")
?.subscribeOn(schedulerProvider!!.io())
?.observeOn(schedulerProvider!!.ui())
?.doOnNext {
run {
spinner.setVisibility(View.VISIBLE)
}
}
?.subscribe(object : FlowableSubscriber<List<Post>> {
override fun onError(t: Throwable?) {
spinner.setVisibility(View.GONE)
spinner.visibility
Snackbar.make(view.findViewById(R.id.linearLayout), "Check Internet Connection!", Snackbar.LENGTH_INDEFINITE)
.setAction("Retry", {})//HERE THE COMMAND SHOULD PASS
.show();
}
override fun onComplete() {
Log.d("TAG", "onComplete: ")
}
override fun onSubscribe(s: Subscription) {
s.request(Long.MAX_VALUE);
}
override fun onNext(posts: List<Post>?) {
spinner.setVisibility(View.GONE)
posts?.let { viewAdapter.setTitleData(it) }
}
})
}
Upvotes: 1
Views: 716
Reputation: 11497
If you want to show the snackbar right away when your call fails, you have to call the subscription again. You could refactor your code as follows:
doNetworkCall()
.handleError(t: Throwable)
. Snackbar
appear, and call the doNetworkCall()
method once the user taps the retry action.Example:
fun doNetworkCall() {
MyViewModel!!.getPost("132")
?.subscribeOn(schedulerProvider!!.io())
?.observeOn(schedulerProvider!!.ui())
// The rest of the code here was removed for brevity.
?.subscribe(object : FlowableSubscriber<List<Post>> {
override fun onError(t: Throwable?) {
spinner.setVisibility(View.GONE)
spinner.visibility
handleError(t) // Call the method here.
}
// The rest of the code here was removed for brevity.
}
fun handleError(t: Throwable?) {
// Here you can also check the type of the error, and perhaps even change the snackbar action depending on it.
Snackbar.make(view.findViewById(R.id.linearLayout), "Check Internet Connection!", Snackbar.LENGTH_INDEFINITE)
.setAction("Retry", doNetworkCall()) // Set the retry action to call the doNetworkCall() method again.
.show()
}
You could also use automatic retries before you prompt anything to the user. That can be achieved by using the Rx retry operator. If your network call fails, it'll automatically subscribe again for a given number of tries.
As stated on the ReactiveX docs:
One variant of retry takes no parameters. It will continue to resubscribe to and mirror the source Observable no matter how many onError notifications it receives.
Another variant of retry takes a single parameter: a count of the number of times it should try to resubscribe to the source Observable when it encounters errors. If this count is exceeded, retry will not attempt to resubscribe again and will instead pass the latest onError notification to its observers.
A third variant of retry takes a predicate function as a parameter. You write this function to accept two arguments: an Integer count of how many retries have taken place thusfar, and a Throwable indicating the error that caused the onError notification. This function returns a Boolean to indicate whether or not retry should resubscribe to and mirror the source Observable. If it does not, then retry passes the latest onError notification to its observers.
Upvotes: 1