Search code examples
javaandroidandroid-roomandroid-livedataobservers

Getting LiveData inside the Repository class and update the Data inside the Database without an endless loop


I'm trying to create an app that only adds an entry to the database if there is no entry already at a specific time intervals and modifies the existing entry if there is already one in the database. I'm using Room.

It works, but only with a workaroud, because I have to call the add function twice before the value gets added (make the input two times before it works). And I also don't like my adding the Observer and immediately removing it afterwards. I also had to implement the workaround when instatiating the DB, with a value when it was first created.

How can I get the data from my LiveData List inside the Repository class and change it without ending up in an endless loop or how do I have to redesign my code to avoid that?

The complete code can be found on my Github account: Github repository

I would really appreciate any suggestion fix my problem and learn to design and plan my code better.

MainActivity

public void ok_clicked(View view) {

    Intent intent = new Intent(this, DataActivity.class);
    ...
    Diary addDiary = new Diary(new Date(), diaryCh.isChecked(), readingCh.isChecked(),writingCh.isChecked(),pianoCh.isChecked(),youtubeCh.isChecked());
    mDiaryViewModel.insert(addDiary);
    startActivity(intent);

}

DiaryViewModel

public void insert(Diary diary) {mRepositroy.add(diary);}

DiaryRepository

public class DiaryRepository {

private DiaryDao mDiaryDao;
private LiveData<List<Diary>> mEntriesToday;
DiaryRepository(Application application) {
    AppDatabase db = AppDatabase.getDatabase(application);
    mDiaryDao = db.diaryDao();
    mEntriesToday = mDiaryDao.findEntriesByDate(Dates.getYesterdayMidnight(), Dates.getTomdayMidnight());
}

LiveData<List<Diary>> getmEntriesToday() { return mEntriesToday;}


void add(Diary diary) {
    Observer<List<Diary>> observerEntriesToday = new Observer<List<Diary>>() {
        @Override
        public void onChanged(List<Diary> diaries) {
            if (diaries != null) {
                Log.e(TAG, "add: with matching entries"+ diaries.get(0) + " add: " +  diary );
                diaries.get(0).addAttributes(diary);
                new updateDiaryAsyncTask(mDiaryDao).execute(diaries.get(0));
            } else {
                Log.e(TAG, "add: without matching entries"+" add: " +  diary );
                new insertDiaryAsyncTask(mDiaryDao).execute(diary);
            }
        }
    };

    getmEntriesToday().observeForever(observerEntriesToday);
    getmEntriesToday().removeObserver(observerEntriesToday);


}

Solution

  • You shouldn't be using LiveData in this scenario at all. It is only a wrapper for data that will be observed from Activity/Fragment.

    First you need to modify mEntriesToday to be MutableLiveData so you can update it. In your case, you can omit using Observer for updating DB, and so something simple like:

    void add(Diary diary){
    
    if (mEntriesToday.getValue() != null) {        
        Log.e(TAG, "add: with matching entries"+ mEntriesToday.getValue().get(0) + " add: " +  diary );
        mEntriesToday.getValue().get(0).addAttributes(diary);
        new updateDiaryAsyncTask(mDiaryDao).execute(mEntriesToday.getValue().get(0));
    } else {
       Log.e(TAG, "add: without matching entries"+" add: " +  diary );
       new insertDiaryAsyncTask(mDiaryDao).execute(diary);
        }
    }
    

    If you need this data, outside this class, then you can use getmEntriesToday() and observe it.