RxAndroid - try again click

I am using rxAndroid and rxKotlin in my Android application to process network requests asynchronously. Now I would like to repeat the failed network request only after clicking the Snackbar button.

My code is:

val citiesService = ApiFactory.citiesService citiesService.cities() .subscribeOn(Schedulers.newThread()) // fetch List<String> .flatMap { Observable.from(it) } // convert to sequence of String .flatMap { city -> citiesService.coordinates(city) // fetch DoubleArray .map { City(city, it) } // convert to City(String, DoubleArray) } .toList() .observeOn(AndroidSchedulers.mainThread()) .doOnNext { listView.setOnItemClickListener { adapterView, view, position, id -> onItemClick(it[position]) } } .map { it.map { it.getName(activity) } } .subscribe( { listAdapter = setupAdapter(it) }, { showErrorSnackbar() } // handle error ) fun showErrorSnackbar() { Snackbar.make(listView, getString(R.string.not_available_msg), Snackbar.LENGTH_INDEFINITE) .setAction(getString(R.string.snack_retry_btn), { // retry observable }) .show() } 

The interface of cities for modernization:

 interface CitiesService { @GET("api/v1/cities") fun cities(): Observable<List<String>> @GET("api/v1/cities/{city}/coordinates") fun coordinates(@Path("city") city: String): Observable<DoubleArray> } 

Api factory:

 object ApiFactory { val citiesService: CitiesService get() = retrofit.create(CitiesService::class.java) private val retrofit: Retrofit get() = Retrofit .Builder() .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .baseUrl(BASE_URL) .build() } 

How can I restart the observable this way?

+5
source share
1 answer

I can offer you a really reactive way, not an imperative way.

Paste this code immediately after the subscribe () method:

 .retryWhen(retryHandler -> retryHandler.flatMap(nothing -> retrySubject.asObservable())) .subscribe() 

Where is the update object:

 @NonNull private final PublishSubject<Void> retrySubject = PublishSubject.create(); 

And when calling snackbar, call this method:

 public void update() { retrySubject.onNext(null); } 

All of the above retryWhen the method will be literally redone.

Although with this approach, the error will never go down to the subscriber, you can add error correction to the flat retryHandler, but this is another story.

PS sorry, it was Java code with retrolambdas, but you can easily convert it to Kotlin.

+1
source

Source: https://habr.com/ru/post/1247774/


All Articles