C. Marr
C. Marr

Reputation: 267

RxJava Observer incompatible types

I am trying to use Retrofit and RxJava to make an API call within a custom view in an app that I am working on, but I encounter an incompatible type error when trying to subscribe to the Observable from my Retrofit API call.

My retrofit interface:

public interface ApiQueryInterface{
// Request method and URL specified in the annotation
// Callback for the parsed response is the last parameter

@GET("users/")
Observable<Users> getUsers (
        @Query("key") String key,
        @Query("address") String address
);

@GET("posts/")
Observable<Posts> getPosts (
        @Query("key") String key,
        @Query("address") String address
);

}

and the Retrofit call located within the onFinishInflate() of the custom view:

        // Create RxJava adapter for synchronous call
    RxJava2CallAdapterFactory rxAdapter = RxJava2CallAdapterFactory.create();

    // Create Retrofit2 instance for API call
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(rxAdapter)
            .build();

    // Make API call using retrofit
    final ApiQueryInterface apiQueryInterface = retrofit.create(ApiQueryInterface.class);

    // API return type defined by interface
    Observable<Users> query = apiQueryInterface
            .getUsers(KEY, ADDRESS)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<Users>() {
                @Override
                public void onSubscribe(Disposable d) {

                }

                @Override
                public void onNext(Users users) {

                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onComplete() {

                }
            });
}

When I build the project I hit an incompatible types error in the custom view on the line beginning with Observable<Users> query = ...:

Error:(60, 27) error: incompatible types: void cannot be converted to Observable<Users>

"Users" is a generic model class which matches the JSON object returned from the API

Upvotes: 4

Views: 4252

Answers (2)

eurosecom
eurosecom

Reputation: 2992

Change returned object to Subscription

private Subscription subscription;

....

subscription = ApiClient.getInstance()
        .getUsers(KEY, ADDRESS)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Observer<List<Users>>() {
                                   @Override public void onCompleted() {

                                   }

                                   @Override public void onError(Throwable e) {

                                   }

                                   @Override public void onNext(List<Users> users) {

                                   }
                               });

apiclient

public class ApiClient {

private static ApiClient instance;
private ApiQueryInterface apiqueryinterface;

private ApiClient() {
    final Gson gson =
        new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
    final Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
                                                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                                                    .addConverterFactory(GsonConverterFactory.create(gson))
                                                    .build();
    apiqueryinterface = retrofit.create(ApiQueryInterface.class);
}

public static ApiClient getInstance() {
    if (instance == null) {
        instance = new ApiClient();
    }
    return instance;
}

public Observable<List<Users>> getUsers(@NonNull String key, @NonNull String address) {
    return apiqueryinterface.getUsers(key, address);
}

}

interface

public interface ApiQueryInterface{
// Request method and URL specified in the annotation
// Callback for the parsed response is the last parameter

@GET("users")
Observable<<List<Users>>  getUsers (
    @Query("key") String key,
    @Query("address") String address
);

Upvotes: 0

Blackbelt
Blackbelt

Reputation: 157437

RxJava 1 returns a Subscription object not an Observable. RxJava 2 subscription returns void. That's why you are getting Error:(60, 27) error: incompatible types. You are getting the Disposable in the callback onSubscribe. If you need a reference to it, you can assign it to a class level member when the callback is invoked

Upvotes: 2

Related Questions