Search code examples
androidnavigationfragmentviewmodelandroid-livedata

How to prevent Live date from duplication in on back pressed from another fragment and on recall


hello i have two problems regarding live data with view model and navigation component first one is when i go from fragment A with live data to fragment B and then from B to A the data in my list gets duplicated, the other problem is one i re call viewModel.loadList() in my fragment after making and event to filter the data also gets duplicated

here is my view model

  public class HomeViewModel extends ViewModel {
  MutableLiveData<ArrayList<HomeResponseModel>> homeLiveData = new MutableLiveData<>();
    ArrayList<HomeResponseModel> homeList = new ArrayList<>();
     public MutableLiveData<ArrayList<HomeResponseModel>> geHomeList(HomeRequestModel homeRequestModel, Context context, ApiInterface apiInterface, LottieAnimationView lottieAnimationView) {
            if (homeLiveData == null) {
                homeLiveData = new MutableLiveData<ArrayList<HomeResponseModel>>();
                loadHomeList(homeRequestModel);

            }
            return homeLiveData;
        }
  public void loadHomeList(HomeRequestModel homeRequestModel) {

            Call<List<HomeResponseModel>> call = apiInterface.getHomeList(homeRequestModel, );
            call.enqueue(new Callback<List<HomeResponseModel>>() {
                @Override
                public void onResponse(Call<List<HomeResponseModel>> call, Response<List<HomeResponseModel>> response) {

                    if (response.isSuccessful()) {
                        homeList.addAll(response.body());
                        homeLiveData.setValue(homeList);
                    }

                }

                @Override
                public void onFailure(Call<List<HomeResponseModel>> call, Throwable t) {

                }
            });


    }

my observer in onCreateView

viewModel.geHomeList(homeRequestModel).observe(getViewLifecycleOwner(), new Observer<ArrayList<HomeResponseModel>>() {
            @Override
            public void onChanged(ArrayList<HomeResponseModel> homeResponse) {


                homeResponseModels.addAll(homeResponse);
                homeAdapter.notifyDataSetChanged();
            }
        });



        }

how i recall load method after a filter event

            viewModel.loadHomeList(homeRequestModel);

Solution

  • Clear the list before adding the new models:

    viewModel.geHomeList(homeRequestModel).observe(getViewLifecycleOwner(), new Observer<ArrayList<HomeResponseModel>>() {
                @Override
                public void onChanged(ArrayList<HomeResponseModel> homeResponse) {
                    homeResponseModels.clear();
                    homeResponseModels.addAll(homeResponse);
                    homeAdapter.notifyDataSetChanged();
                }
            });
    }
    

    Or, even better:

    In case your adapter holds a List or HomeResponseModel you could create a method to update it:

    public update(List<HomeResponseModel> homeResponse) {
        this.homeResponseModels = homeResponse;
        notifydatasetchanged();
    }
    

    and then change the observe method to call it:

    viewModel.geHomeList(homeRequestModel).observe(getViewLifecycleOwner(), new Observer<ArrayList<HomeResponseModel>>() {
                @Override
                public void onChanged(ArrayList<HomeResponseModel> homeResponse) {
                    homeAdapter.update(homeResponse);
                }
            });
    }
    

    Besides that, in your ViewModel in the loadHomeList method in the onResponse callback you could assign the data received to the liveData:

    if (response.isSuccessful()) {
        homeLiveData.setValue(response.body());
    }
    

    no need to save it in the homeList var, you can get rid of that var. Otherwise, perform homeList.clear(); before adding to it all the received data to avoid duplicates.