I have a searchBar (an EditText
) with four tabs below it (each tab should display different results). I'm using RxJava with RxBinding to listen and react to text changes events, and I'm using switchMap() operator to execute a Retrofit service for each text change emission.
Since user can select any of the four tabs I actually execute the corresponding Retrofit
request for that tab.
For each of those Retrofit
services I receive a different response object.
How can I handle different return types inside switchMap()
since the last one needs a common type for all?
I have already asked a similar question previously but the answer while it works doesn't lets me to consume the data from my subscriber. Or is my approach wrong from the beginning and I should try a different approach ?
Code :
RxTextView.textChangeEvents(searchbar.getEditText())
.debounce(400, TimeUnit.MILLISECONDS)
.filter(new Func1<TextViewTextChangeEvent, Boolean>() {
@Override
public Boolean call(TextViewTextChangeEvent text) {
return (text.text().length() > 2);
}
})
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(Schedulers.io())
.switchMap(new Func1<TextViewTextChangeEvent, Observable<Void>>() {
@Override
public Observable<Void> call(TextViewTextChangeEvent textViewTextChangeEvent) {
String searchBarText = textViewTextChangeEvent.text().toString();
switch (visibleTab) {
case TAGS:
presenter.executeSearchPostsByTag(searchBarText, String.valueOf(0));
case PEOPLE:
return presenter.executeSearchPostsByPeople(searchBarText, String.valueOf(0));
case COMPANIES:
return presenter.executeSearchPostsByCompanies(searchBarText, String.valueOf(0));
case JOBS:
return presenter.executeSearchPostsByJobs(searchBarText, String.valueOf(0));
default:
return presenter.executeSearchPostsByTag(searchBarText, String.valueOf(0));
}
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Void>() {
@Override
public void onCompleted() {
Timber.i("ON COMPLETED");
}
@Override
public void onError(Throwable e) {
Timber.i("ON ERROR e : %s", e.getMessage());
}
@Override
public void onNext(Void aVoid) {
Timber.i("ON NEXT");
}
});
In the code above you 'll see that I have return type of Observable but that doesn't works I just added it so you 'll see what I'm doing.
Thing is, do any of the
executeSearchPostsBy*
methods return a non-empty Observable? If all of their Observables are empty, then you can just tack on.cast(Void.class)
to all of them. If they do return non-empty observables but you don't care about the items, then tack on.ignoreElements().cast(Void.class)
.If you need to do some processing for anything that is returned, then you should do that in different methods, in their own Observable chains.
If you need to do some processing that is common to all of them, then you need to adjust your model to reflect this, even if it's just wrapper classes.