Rafa
Rafa

Reputation: 153

Why retrofit returning Null 'LiveData' even after setting return value non-null correctly?

I got the response correctly, set value of LiveData correctly (got confirmed by printing value on console after setting value to live data). But When i tried to print same thing just before "return" it's giving me NullPointerException.

public class ProjectRepository {

private ProjectRepository instance;
Context context;
public ProjectRepository(Context context) {
  this.context=context;
}
private MutableLiveData<List<PojoDivision>> data = new MutableLiveData<>();
public LiveData<List<PojoDivision>> getDivisionList() {
    ((RetrofitConfiguration)context).getDivisionRestApiWithAuthentication().getDivisionList().enqueue(new Callback<List<PojoDivision>>() {
        @Override
        public void onResponse(Call<List<PojoDivision>> call, Response<List<PojoDivision>> response) {

            if (response.isSuccessful()) {
                System.out.println(response.body().get(4).getName()); // this is printing

                data.setValue(response.body());
                System.out.println(data.getValue().get(4).getName()); // this is printing
            }
        }

        @Override
        public void onFailure(Call<List<PojoDivision>> call, Throwable t) {
            Log.d(TAG, t.getMessage());
        }
    });
    /*
    following code is not printing with nullPointerException
    java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object java.util.List.get(int)' on a null object reference
     */
    System.out.println(data.getValue().get(4).getName());
    return data;
}

}

Upvotes: 0

Views: 948

Answers (1)

Chris
Chris

Reputation: 1220

Since you're using a LiveData object at the class level for your repository class, your method has no need to return anything. Instead it's responsibility is for updating that LiveData object.

public class ProjectRepository {
    private static final String TAG = "ProjectRepository";

    private ProjectRepository instance;
    Context context;

    public ProjectRepository(Context context) {
        this.context = context;
    }

    public MutableLiveData<List<PojoDivision>> data = new MutableLiveData<>();

    public void getDivisionList() {
        ((RetrofitConfiguration) context).getDivisionRestApiWithAuthentication().getDivisionList().enqueue(new Callback<List<PojoDivision>>() {
            @Override
            public void onResponse(Call<List<PojoDivision>> call, Response<List<PojoDivision>> response) {

                if (response.isSuccessful()) {
                    data.postValue(response.body());
                }
            }

            @Override
            public void onFailure(Call<List<PojoDivision>> call, Throwable t) {
                Log.d(TAG, t.getMessage());
            }
        });
    }

}

The clients of this class would need to 1) observe the LiveData object, and 2) call the getDivisionList() method to trigger an update:

class MyFragment extends Fragment {

    private ProjectRepository repository;

    private void setRepository() {
        Context context = getContext();
        if (context == null) return;
        repository = new ProjectRepository(context);
    }

    public void observeData() {
        repository.data.observe(this, new Observer<List<PojoDivision>>() {
            @Override
            public void onChanged(List<PojoDivision> pojoDivisions) {
                // do something with updated data
            }
        });
    }

    public void triggerUpdate() {
        repository.getDivisionList();
    }
}

Upvotes: 1

Related Questions