Search code examples
androidandroid-livedatamutablelivedata

LiveData - not getting data in fragment on second call


I am using LiveData to get data from the server. In the onResume method, Calling same function every after 5 second I am able to get data only on the First API call. Second time the observer is not triggered and not able to get data in the fragment.

this is my fragment:

    private int delay = 5 * 1000;
    private ViewModel mViewModel;
    private DetailsModel details = new DetailsModel();

    mViewModel = ViewModelProviders.of(this).get(ViewModel.class);
    mViewModel.getDetailsResponse("token", "ids");

    mViewModel.getData().observe(this, new Observer< DetailsModel >() {
                    @Override
                    public void onChanged(DetailsModel response) {

                        details = response;

                    }});
//getting data in every 5 seconds
@Override
    public void onResume() {
        super.onResume();

        liveHandler.postDelayed(runnable = new Runnable() {
            public void run() {
                mViewModel. getDetailsResponse("token", "ids");
                liveHandler.postDelayed(runnable, delay);
            }
        }, delay);
    }

ViewModel.java

 private MutableLiveData<DetailsModel> detailsResponse;
    private ProjectRepository repository  = new ProjectRepository();

    public void getDetailsResponse(String token, String ids) {
        detailsResponse = repository.getMapData("token", "ids");
    }

    public MutableLiveData<DetailsModel> getData() {
        return detailsResponse;
    }

ProjectRepository.java

public MutableLiveData<DetailsModel> getMapData(String token, String ids) {
        final MutableLiveData<DetailsModel> responseMutableLiveData = new MutableLiveData<>();

        Call<DetailsModel> call = service.getMapDetails(token, ids);
        call.enqueue(new Callback<DetailsModel>() {
            @Override
            public void onResponse(@NonNull Call<DetailsModel> call, @NonNull Response<DetailsModel> response) {
                responseMutableLiveData.postValue(response.body());
            }

            @Override
            public void onFailure(@NonNull Call<DetailsModel> call, @NonNull Throwable t) {
                t.printStackTrace();
            }
        });
        return responseMutableLiveData;
    }

Solution

  • Whenever you call getDetailsResponse, you create a new LiveData object, which is the problem, you should do this in your ProjectRepository

    final MutableLiveData<DetailsModel> responseMutableLiveData = new MutableLiveData<>();
    
    public MutableLiveData<DetailsModel> getMapData(String token, String ids) {
            Call<DetailsModel> call = service.getMapDetails(token, ids);
            call.enqueue(new Callback<DetailsModel>() {
                @Override
                public void onResponse(@NonNull Call<DetailsModel> call, @NonNull Response<DetailsModel> response) {
                    responseMutableLiveData.postValue(response.body());
                }
    
                @Override
                public void onFailure(@NonNull Call<DetailsModel> call, @NonNull Throwable t) {
                    t.printStackTrace();
                }
            });
            return responseMutableLiveData;
        }
    

    And in your VM:

    private MutableLiveData<DetailsModel> detailsResponse = null;
    private ProjectRepository repository  = new ProjectRepository();
    
    public void getDetailsResponse(String token, String ids) {
            if (detailsResponse == null) {
               detailsResponse = repository.getMapData("token", "ids");
            } else {
               // Just call it, you already assigned before
               repository.getMapData("token", "ids");
            }
    }
    
    public MutableLiveData<DetailsModel> getData() {
            return detailsResponse;
    }
    

    So, basically move the object creation out of the function itself. However, the design of your MVVM implementation can be simplified a lot. I would urge to check some examples!