Sriram R
Sriram R

Reputation: 2229

Not able to return a list of objects from retrofit response

I'm using retrofit library to do API calls for my app. I wrote a seperate function for the API so that it is re usable. The response I'm getting back is a list of the object 'Movies' . But im not able to return the object . What should I do here?

The function which gets the data from API

   // These are the retrofit codes to get the data from TMDB API
    private List<Movies> getDataFromServer(int page)
{
     ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);

    Call<Response> call = apiService.getPopularMovies(API_KEY , page);

    List<Movies> movies = new ArrayList<>();

    call.enqueue(new Callback<Response>() {
        @Override
        public void onResponse(Call<Response> call, retrofit2.Response<Response> response) {
            movies = response.body().getMovies();
        }

        @Override
        public void onFailure(Call<Response> call, Throwable t) {
            Log.e(TAG,t.toString());
            movies = null;
        }
    });
     return movies;

}

It says that I should declare the movies as final but when I do , it automatically converts the array list into an array and the movies inside the onResponse and onFailure is turned into moviess[0]. I just want to get the movies , and then return it as a List

Upvotes: 1

Views: 4239

Answers (3)

Arpan Sharma
Arpan Sharma

Reputation: 2162

The problem is that you are calling from onResponse which is a callback method and will take time to load data and come and load them in your movies list.You will never know when the response will be receiver , therefore taking a return is not a good idea.You should continue whatever you are doing from inside of onResponse().

 @Override
    public void onResponse(Call<Response> call, retrofit2.Response<Response> response) {
       if (response.isSuccessful())  {  
        movies = response.body().getMovies();
//continue whatever you want do from here when the response is received.
         }

  }

Upvotes: 1

Farid
Farid

Reputation: 1086

i think you are using android studio's features to change the modifier to final but it does not work as you wish and changing the movies modifier ti final wont fix your problem because you fetch data in another thread and you just return null.you can declare a method to call when you fetched data then do what ever you want with it

//declare movies as a class field
List<Movies> movies;
...
private List<Movies> getDataFromServer(int page)
{
...
call.enqueue(new Callback<Response>() {
    @Override
    public void onResponse(Call<Response> call, retrofit2.Response<Response> response) {
        dataIsReady(response.body().getMovies();
    }

    @Override
    public void onFailure(Call<Response> call, Throwable t) {
        Log.e(TAG,t.toString());
        movies = null;
    }
});
}

private void dataIsReady(List<Movies> movies){
    this.movies = movies;
  //do what you want with movies
}

Upvotes: 0

Reza.Abedini
Reza.Abedini

Reputation: 2257

You can declare your movies list as a field in your class and then write something like this :

private List<Movies> getDataFromServer(int page)
{
         ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);

    Call<Response> call = apiService.getPopularMovies(API_KEY , page);


    call.enqueue(new Callback<Response>() {
        @Override
        public void onResponse(Call<Response> call, retrofit2.Response<Response> response) {
           if (response.isSuccessful())  {  
            movies = response.body().getMovies(); }
           else{
           //show error
           }

        }

        @Override
        public void onFailure(Call<Response> call, Throwable t) {
            Log.e(TAG,t.toString());
            movies = null;
        }
    });
     return movies;

}

also remember to check that your response is Successful.

Upvotes: 1

Related Questions