Simplifying code with Transformations

ObservableTransformer is a simple interface that defines a transformation on the Observable object as a whole instead of the individual items that the Observable produces. The ObservableTransformer interface is as follows:

package io.reactivex;

public interface ObservableTransformer<Upstream, Downstream> {
ObservableSource<Downstream> apply(Observable<Upstream> upstream);
}

Here, the .apply() method will apply a series of operations on the upstream (original) Observable when used in the .compose() method on the Observable.

Let's see an example with the error handling code that we examined before:

.observeOn(AndroidSchedulers.mainThread())
.doOnError(this::showToastErrorNotificationMethod)
.observeOn(Schedulers.io())

We can wrap these three operations in the ObservableTransformer interface and pass it to the .compose(), as shown here:

.compose(new ObservableTransformer<StockUpdate, StockUpdate>() {
@Override
public ObservableSource<StockUpdate> apply(Observable<StockUpdate>
upstream) {
return upstream.observeOn(AndroidSchedulers.mainThread())
.doOnError(MainActivity.this::showToastErrorNotificationMethod)
.observeOn(Schedulers.io());
}
})

Here, we have used an anonymous inner class to implement the interface for the sake of clarity, but we might as well use lambda, as follows:

.compose(
upstream -> upstream.observeOn(AndroidSchedulers.mainThread())
.doOnError(MainActivity.this::showToastErrorNotificationMethod)
.observeOn(Schedulers.io())
)

Now, we can take this one step further by extracting a method to represent this logical action:

ObservableTransformer<StockUpdate, StockUpdate> addUiErrorHandling()

This will make the entire flow code to be as shown:

Observable.merge(
createFinancialStockUpdateObservable(yahooService, query, env),
createTweetStockUpdateObservable(configuration,
trackingKeywords,
filterQuery)
)
.compose(bindToLifecycle())
.subscribeOn(Schedulers.io())
.doOnError(ErrorHandler.get())
.compose(addUiErrorHandling())
.doOnNext(this::saveStockUpdate)
.onExceptionResumeNext(StorIOFactory
.createLocalDbStockUpdateRetrievalObservable(this))

Here, the body of the addUiErrorHandling() method is this:

@NonNull
private ObservableTransformer<StockUpdate, StockUpdate> addUiErrorHandling() {
return upstream -> upstream.observeOn(AndroidSchedulers.mainThread())
.doOnError(MainActivity.this::showToastErrorNotificationMethod)
.observeOn(Schedulers.io());
}

This is just to quickly remind you why we need those three lines. The following line is needed because the UI modification needs to happen on the UI thread on Android:

.observeOn(AndroidSchedulers.mainThread())

The next line shows the actual error message using the Toast interface:

.doOnError(MainActivity.this::showToastErrorNotificationMethod)

The following one returns the Observable to the original scheduler that we were using before--the IO scheduler:

.observeOn(Schedulers.io())
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.226.240