androidlambdarefactoringrx-java

Is there a way to refactor this RxJava code?


I have my Observable subscription that looks like:

      compositeDisposables.add(githubService.getRepos()
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(
                            (List<GithubRepo> value) -> {
                                if (!value.isEmpty()) {
                                    ArrayAdapter<GithubRepo> adapter = new 
     ArrayAdapter<GithubRepo>
                                            (MainActivity.this,

     android.R.layout.simple_spinner_dropdown_item, value);
                                    reposSpinner.setAdapter(adapter);
                                    reposSpinner.setEnabled(true);
                                } else {
                                    showEmptyRepoAdapterState();
                                }
                            },
                            (Throwable e) -> {
                                e.printStackTrace();
                                Toast.makeText(this, "Cannot load repositories", Toast
                                        .LENGTH_SHORT).show();
                            }));

Is there a way to abstract all the code in the subscribe() method to a separate method? I've tried doing this:

private DisposableSingleObserver<List<GithubRepo>> getRepos(){
    return (List<GithubRepo> value) -> {
        if (!value.isEmpty()) {
            ArrayAdapter<GithubRepo> adapter = new ArrayAdapter<GithubRepo>
                    (MainActivity.this,
                            android.R.layout.simple_spinner_dropdown_item, value);
            reposSpinner.setAdapter(adapter);
            reposSpinner.setEnabled(true);
        } else {
            showEmptyRepoAdapterState();
        }
    },
    (Throwable e) -> {
        e.printStackTrace();
        Toast.makeText(this, "Cannot load repositories", Toast
                .LENGTH_SHORT).show();
    };
};

But I get an error: Target type of a lambda conversion must be an interface.

So, is there a way to refactor this code?? How do I even know the expected return value?


Solution

  • I figured it out. The method signature that I used required two Consumer parameters so the huge block of code I had could be refactored to this:

      compositeDisposables.add(githubService.getRepos()
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(
                                successResponse(),
                                errorResponse()
                        ));
    

    And then the parameters looked like:

        private Consumer<List<GithubRepo>> successResponse() {
        return (List<GithubRepo> value) -> {
            if (!value.isEmpty()) {
                ArrayAdapter<GithubRepo> adapter = new ArrayAdapter<GithubRepo>
                        (MainActivity.this,
                                android.R.layout.simple_spinner_dropdown_item, value);
                reposSpinner.setAdapter(adapter);
                reposSpinner.setEnabled(true);
            } else {
                showEmptyRepoAdapterState();
            }
        };
    }
    

    And

         private Consumer<Throwable> errorResponse() {
        return (Throwable e) -> {
            e.printStackTrace();
            Toast.makeText(this, "Cannot load repositories", Toast
                    .LENGTH_SHORT).show();
        };
    }