0

I am trying to observe the data inside a specific table by getting the elements using a Flowable<List<T>>, converting it to LiveData by using the library LiveDataStreams and then observing this last one. The observation must start on button click. First time I user clicks the button, it downloads data from server, saves it into the correspondent table and then sets up the observer. The problem becomes when I click again on the button, because it downloads the data and save it into the table, but it does not call the onChanged method from the Observer.

In the code you see that ParentFragment's onViewCreated method calls showItemsList in there because the other children fragments have to do it like this, but just for this current case I have to start observing the list after the buttons' onclick.

ParentFragment:

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    mNavController = Navigation.findNavController(getDataBindingObject().getRoot());

    showItemsList();
}

protected void showItemsList() {
    mViewModel.getList().observe(getViewLifecycleOwner(), listObserver);
}

protected final Observer<List<T>> listObserver = new Observer<List<T>>() {
    @Override
    public void onChanged(List<T> list) {
        getAct().getSupportActionBar().setTitle(getString(mViewModel.getTitleId(), list.size()));
        mViewModel.setListAdapter(list);
    }
};

ChildFragment (current case):

@Override
protected void showItemsList() {
    mDataBinding.searchButton.setOnClickListener(v -> {
        mViewModel.download()
                .subscribe(downloaded -> super.showItemsList()
                        , t -> DialogUtils.showMessage(R.string.error_binding_data));
    });
}

ViewModel:

public LiveData<List<T>> getList() {
    if (list == null) {
        LiveData<List<T>> lD = LiveDataReactiveStreams.fromPublisher(mRepository.getList());
        list = new MediatorLiveData<>();
        list.addSource(lD, l -> {
            list.setValue(l);
            list.remove(lD);
        });
    }
    return list;
}

Repository:

public Flowable<List<T>> getList() {
    if (list == null) list = dao.getItems();
    return list;
}

Dao:

public abstract Flowable<List<MyItem>> getItems();
mantc_sdr
  • 451
  • 3
  • 17

1 Answers1

0

You made a mistake in the code responsible for conversion from Flowable to LiveData.

Upon first call of getList(), you create a LiveData object which observes Flowable, but after retrieving first item, you stop observing the Flowable. Later you assign this LiveData to a field.

On second call of getList(), you get LiveData object assigned to the field (which has no sources), and thus the observer in your fragment is not notified.

You can modify your code like this

public LiveData<List<T>> getList() {
    if (list == null) {
        LiveData<List<T>> lD = LiveDataReactiveStreams.fromPublisher(mRepository.getList());
        list = new MediatorLiveData<>();
        list.addSource(lD, l -> {
            list.setValue(l);
        });
    }
    return list;
}