Starting again a Retrofit call subscribing the Observable again from onError Callback in RXJava
Starting again a Retrofit call subscribing the Observable again from onError Callback in RXJava
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?
onError
Snackbar
setAction()
NameActivity()
Snackbar
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)
)
}
1 Answer
1
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
doNetworkCall()
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.
retry
SnackBar
doNetworkCall()
You can create a method outside
doNetworkCall()
to handle the errors, and call this method inside the Rx's onError
.– Mauker
Aug 29 at 18:02
doNetworkCall()
onError
first of all if I wrap all the code I published I have to inject also the View so that would be
fun doNetworkCall(view:View)
because I have instance of the view for the SnackBar
and ProgressBar
, but the central problem is how I can isolate onError
as a method? I am trying but as expected does not work because onError should go into a subscription to an Observable that is basically all the method doNetworkCall(view:view)
I mean Observable.subscribe(//here are called the 4 rxjava callBacks, and cannot isolate OnError apart!)
– Drocchio
Aug 29 at 18:10
fun doNetworkCall(view:View)
SnackBar
ProgressBar
onError
doNetworkCall(view:view)
Observable.subscribe(//here are called the 4 rxjava callBacks, and cannot isolate OnError apart!)
You're very welcome, glad to be of help!
– Mauker
Aug 29 at 18:22
glad to learn a lot by the community and give back
– Drocchio
Aug 29 at 18:27
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Thanks.Well
retry
operator does not fit my use case because cannot be called from insideSnackBar
Listener, so I would like to implement the solution you mention, but how can I implement point 2 if onError get called inside the Subscriber Callbacks and not in a separate method, in other words is inside thedoNetworkCall()
you suggest at point one– Drocchio
Aug 29 at 18:00