Search code examples
androidmvvmviewmodelandroid-livedatamutablelivedata

call MutableLiveData web service agine to update the list


I use MVVM structure in my project. I have the main fragment with list observed a web service as you can see in the code

fragment :

mViewModel.getHomePageList().observe(this, homeDataWrapper -> {
           if (homeDataWrapper!=null) {
               if (homeDataWrapper.isStatus()) {
                   binding.homeProgressBar.setVisibility(View.INVISIBLE);
                   ToastUtil.showTosat(homeDataWrapper.getData().getMessage(), getContext());
                   Log.d(TAG, "onChanged: ");
               }
           }
       });

view model:

ublic class HomePageViewModel extends AndroidViewModel {
    private MutableLiveData<DataWrapper<Home>> data;
    public ObservableInt loading;
    private HomeRepository homeRepository;
    private HomePageAdapter adapter;

    public HomePageViewModel(@NonNull Application application) {
        super(application);
    }

    public void init() {
        adapter = new HomePageAdapter(R.layout.main_page_list, this);
        homeRepository = new HomeRepository();
        if (this.data != null) {
            // ViewModel is created per Fragment so
            // we know the userId won't change
            return;
        }
        data = homeRepository.getHomeScreen();

    }


    public HomePageAdapter getAdapter() {
        return adapter;
    }

    public void onItemClick(Integer index) {

    }

    public void onSerachClicked(View view) {
        Navigation.findNavController(view).navigate(R.id.action_homePageFragment_to_searchActivity);
    }



    public MutableLiveData<DataWrapper<Home>> getHomePageList() {
        return this.data;
    }

}

HomeRepository :

public MutableLiveData<DataWrapper<Home>> getHomeScreen() {
    final MutableLiveData<DataWrapper<Home>> homeMutableLiveData = new MutableLiveData<>();
    final DataWrapper<Home> dataWrapper = new DataWrapper<>();
    RetrofitInstance.getApiService().getHome().enqueue(new Callback<Home>() {
        @Override
        public void onResponse(@NotNull Call<Home> call, @NotNull Response<Home> response) {
            Log.d("", "onResponse: " + response);
            if (response.code() == 200) {
                dataWrapper.setData(response.body());
                dataWrapper.setStatus(true);
                homeMutableLiveData.postValue(dataWrapper);
            }

        }

        @Override
        public void onFailure(Call<Home> call, Throwable t) {
            Log.d("", "onResponse: " + t);
            dataWrapper.setApiException((Exception) t);
            dataWrapper.setStatus(false);
            homeMutableLiveData.postValue(dataWrapper);
        }
    });

    return homeMutableLiveData;
}

I would like to add SwipeRefreshLayout to update the main list. what is the correct way to call the web service again and update the list? can anyone help me?


Solution

  • You can just call getHomeScreen form your Repository class to trigger data pulling from the server again, after pulling request completed, the observers will be notified using the the MutableLiveData.

    But here is your issue, you are creating a new MutableLiveData object each time you call getHomeScreen. Thus, the first one will not be notified and the list will not be updated!

    To solve the problem you have to initialize your MutableLiveData somewhere else so it will not be created again every time you call getHomeScreen.

    I suggest you make your HomeRepository class a singleton class and initialize the MutableLiveData object inside the constructor, then you can use this object to post data to observers once you got new data from the server.

    public class HomeRepository {
    
        private static HomeRepository instance;
        private MutableLiveData<DataWrapper<Home>> homeMutableLiveData;
    
        public static HomeRepository getInstance() {
            if(instance == null) instance = new HomeRepository();
            return instance;
        }
    
        private HomeRepository() {
            homeMutableLiveData = new MutableLiveData<>();
        }
    
        public MutableLiveData<DataWrapper<Home>> getHomeScreen() {
            final DataWrapper<Home> dataWrapper = new DataWrapper<>();
            RetrofitInstance.getApiService().getHome().enqueue(new Callback<Home>() {
                @Override
                public void onResponse(@NotNull Call<Home> call, @NotNull Response<Home> response) {
                    Log.d("", "onResponse: " + response);
                    if (response.code() == 200) {
                        dataWrapper.setData(response.body());
                        dataWrapper.setStatus(true);
                       homeMutableLiveData.postValue(dataWrapper);
                    }
    
                }
    
                @Override
                public void onFailure(Call<Home> call, Throwable t) {
                    Log.d("", "onResponse: " + t);
                    dataWrapper.setApiException((Exception) t);
                    dataWrapper.setStatus(false);
                    homeMutableLiveData.postValue(dataWrapper);
                }
            });
    
            return homeMutableLiveData;
        }
    
    }