Reputation: 1691
I have an EditText
and right below it there are four tabs in a ViewPager
and what I'm currently doing is executing a request to a Rest service using Retrofit
when text changes.
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<?>>() {
@Override
public Observable<?> call(TextViewTextChangeEvent textViewTextChangeEvent) {
String searchBarText = textViewTextChangeEvent.text().toString();
switch (visibleTab) {
case TAGS:
return 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))
.toCompletable().toObservable();
}
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Object>() {
// here I use EventBus to pass the results to the Fragments (Tabs)
// ... code omitted ...
As you can notice from the code for each Tab I have a different request.
But now the requirements have changed and for every text change there is in the EditText
I have to execute all four requests concurrently.
I searched a lot and what I have found out is that I can use combineLatest' so I added all four calls to
combineLatest` but since they all depend on text changes nothing happened.
Observable.combineLatest(presenter.executeSearchPostsByTag( /** what to add as queryText **/ ),
presenter.executeSearchPostsByJobs(/** what to add here as queryText**/), //omits the other two calls)
As you see right above I don't know how to pass the queryText
. There must be a way combining the combineLatest
code with the RxTextView.textChangeEvents(searchbar.getEditText())...
code until the switchMap
I posted at the beginning but I couldn't find it.
EDIT : well maybe combineLatest
was wrong, and I could do something like :
.map(new Func1<String, Boolean>() {
@Override
public Boolean call(String s) {
presenter.executeSearchPostsByTag(s, String.valueOf(0));
presenter.executeSearchPostsByPeople(s, String.valueOf(0));
presenter.executeSearchPostsByJobs(s, String.valueOf(0));
presenter.executeSearchPostsByCompanies(s, String.valueOf(0));
return true;
}
})
but then I don't know how to get the results to the subscriber
Upvotes: 0
Views: 295
Reputation: 5521
You are close. Just replace the switchmap with:
.flatMap(new Func1<TextViewTextChangeEvent, Observable<CombinedData>>() {
@Override
public Observable<CombinedData> call(TextViewTextChangeEvent textViewTextChangeEvent) {
String searchBarText = textViewTextChangeEvent.text().toString();
return Observable.combineLatest(
presenter.executeSearchPostsByTag(searchBarText, String.valueOf(0)),
presenter.executeSearchPostsByPeople(searchBarText, String.valueOf(0)),
...);
}
})
For better readability, create a method to extract the combine part. Something like:
Observable<CombinedData> fetchData(String searchBarText) {
return Observable.combineLatest(
presenter.executeSearchPostsByTag(searchBarText, String.valueOf(0)),
presenter.executeSearchPostsByPeople(searchBarText, String.valueOf(0)),
...);
}
But if you can, it would be better to split it in four pieces. Declare an Observable:
Observable<TextViewTextChangeEvent> requestObservable = 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());
Then you subscribe four times, for each request:
.flatMap(new Func1<TextViewTextChangeEvent, Observable<Post>>() {
@Override
public Observable<Post> call(TextViewTextChangeEvent textViewTextChangeEvent) {
String searchBarText = textViewTextChangeEvent.text().toString();
return presenter.executeSearchPostsByTag(searchBarText, String.valueOf(0));
}
})
.subscribe(...
Upvotes: 1