Search code examples
androidretrofitretrofit2

Return data from retrofit onResponse


Im doing a basic android app that performs a simple login againts an API. I need to return the received data but the retrofit onResponse method has void return type. My code is:

package com.example.deberesloginjava.data;

import android.util.Log;

import com.example.deberesloginjava.data.APIServices.Post;
import com.example.deberesloginjava.data.model.LoggedInUser;

import java.io.IOException;

import com.example.deberesloginjava.data.APIServices.APIService;
import com.example.deberesloginjava.data.APIServices.ApiUtils;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

import static android.content.ContentValues.TAG;

/**
 * Class that handles authentication w/ login credentials and retrieves user information.
 */

public class LoginDataSource {

    private APIService mAPIService;

    public void getData(Callback<Result<LoggedInUser>> callback){
        apiClient.getData().enqueue(callback);
    }

    public Result<LoggedInUser> login(String username, String password) {

        try {

            mAPIService = ApiUtils.getAPIService();

           mAPIService.login(username, password, "password").enqueue(new Callback<Post>() {
                @Override
                public void onResponse(Call<Post> call, Response<Post> response) {
                    if(response.isSuccessful()) {
                        LoggedInUser loggedInUser;
                        loggedInUser = new LoggedInUser(response.body().getUserName(),response.body().getUserName(), response.body().getAccess_token());
                        return new Result.Success<>(loggedInUser);
                    }
                }



                @Override
                public void onFailure(Call<Post> call, Throwable t) {
                    Log.e(TAG, "Unable to submit post to API.");
                }
            });

        } catch (Exception e) {
            return new Result.Error(new IOException("Error logging in", e));
        }
    }
}

I have found at least two questions like this and both have almost the same solution with callbacks but im not able to replicate it in my case.

Thanks in advance.


Solution

  • You have to add custom callback for handle this case. you can't return anything inside onResponse() and onFailure()

    public interface CustomCallback {
    
        void onSucess(Result<LoggedInUser> value);
        void onFailure();
    }
    

    Update your method like this:

    public void login(String username, String password,CustomCallback customCallback) {
    
            try {
    
                mAPIService = ApiUtils.getAPIService();
    
               mAPIService.login(username, password, "password").enqueue(new Callback<Post>() {
                    @Override
                    public void onResponse(Call<Post> call, Response<Post> response) {
                        if(response.isSuccessful()) {
                            LoggedInUser loggedInUser;
                            loggedInUser = new LoggedInUser(response.body().getUserName(),response.body().getUserName(), response.body().getAccess_token());
                            customCallback.onSucess(new Result.Success<>(loggedInUser));
                        }
                    }
    
    
                    @Override
                    public void onFailure(Call<Post> call, Throwable t) {
                        Log.e(TAG, "Unable to submit post to API.");
                        customCallback.onFailure();
                    }
                });
    
            } catch (Exception e) {
                e.printStactTrace();
            }
        }
    

    You have to call your api like below:

    login("user name","passwor",new CustomCallback(){
           @Override
           public void onSucess(Result<LoggedInUser> value){
          //do your success code here
         }
           @Override
           public void onFailure(){
          }
    
    });