How I would use SwitchMap (RXJAVA) in my code?

I'm new to Android development and am currently trying to make a simple MVC app that works with Rest API. API calls are made without using Retrofit, although this is not so important. The main catch is that using Observable with debounce and SwitchMap I still get too many API calls (and the extra ones should be discarded). The function is called when text is entered (EditText Listener with TextWatcher). And when administered continuously without delay word, every symbol processed by the server and should only be administered when not within 600 milliseconds. Please help me.

public Observable<String> getObservable(final String s){
    return  Observable
            .create(new ObservableOnSubscribe<String>() {
        @Override
        public void subscribe(ObservableEmitter<String> emitter) throws Exception {
            emitter.onNext(model.translateText(s));
        }
    });
}

public Observer<String> observer = new Observer<String>() {
    @Override
    public void onSubscribe(Disposable d) {

    }

    @Override
    public void onNext(String s) {
        mainView.hideProgress();
        mainView.showResult(s);
    }

    @Override
    public void onError(Throwable e) {

    }

    @Override
    public void onComplete() {

    }
};


public void onEditTextChange(String textForTranslate){
    mainView.showProgress();
    getObservable(textForTranslate)
            .debounce(600,TimeUnit.MILLISECONDS)
            .switchMap(new Function<String, ObservableSource<String>>() {
                @Override
                public ObservableSource<String> apply(String s) throws Exception {
                    return Observable.just(s);
                }
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(observer);
}

Upvotes: 0

Views: 1074

Answers (1)

Arslan Shoukat
Arslan Shoukat

Reputation: 439

You are creating a new observable every time a character is typed. So multiple observers are created with each having separate debounce (time throttle) and switch but they are not reused. Instead you create a new observable whenever text changes and start rx chain on it.

You need to create a single PublishSubject

private final PublishSubject<String> querySubject = PublishSubject.create();

that emits entered text/query whenever text is changed. Use it in your callback:

public void onEditTextChange(String textForTranslate) {
    querySubject.onNext(textForTranslate);
}

And in your main function, subscribe to observable:

querySubject
        .debounce(600, TimeUnit.MILLISECONDS)
        .distinctUntilChanged()
        .switchMap(new Function<String, ObservableSource<String>>() {
            @Override
            public ObservableSource<String> apply(String s) throws Exception {
                  //  perform api call or any other operation here
                  return Observable.just(s);
               }
            })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(observer);

Debounce operator emits single item only after given time (600 ms) has passed. It ignores items if current item is being processed and given time has not passed. distinctUntilChanged helps in reducing processing of same query.

Upvotes: 2

Related Questions