0

I've got a repository which gets a list of values from the Room Database. I have two Fragments: one contains a RecyclerView which displays values from this repository, and a DialogFragment in which I add a new value to the database. I use different DAOs and though a new value is added to the Database, the list in the Fragment doesn't change though Database Inspector shows that a new value is in the db. Here's my Database code.

@Database(entities = [DatabaseBand::class], version = 1, exportSchema = false)
abstract class BandsDatabase : RoomDatabase() {
    abstract val bandDatabaseDao: BandDatabaseDao
    companion object {
        @Volatile
        private var INSTANCE: BandsDatabase? = null
        fun getInstance(context: Context): BandsDatabase {
            synchronized(this) {
                var instance = INSTANCE
                if (instance == null) {
                    instance = Room.databaseBuilder(context.applicationContext,
                        BandsDatabase::class.java,
                        "test_band_database")
                        .fallbackToDestructiveMigration()
                            .setJournalMode(JournalMode.TRUNCATE)
                        .build()
                }
                return instance
            }
        }
    }
}

What's the right way to solve this problem? Pass the DAO as an argument or insert values to the db only in the Fragment that contains that DAO?

Edit:

In the Main Fragment I have ViewModel that contains LiveData<List<DatabaseBand>> property. There I also have a DAO. In the DialogFragment I have another DAO (in both Fragments I use application context to get the DAO). I just insert a new Item into the DB. In the DAO I use this query:

@Query("SELECT * FROM bands_table")
    fun getAll(): LiveData<List<DatabaseBand>>

It returns LiveData, I observe it. When I add an element using another DAO the observer doesn't trigger. When I use DAO from this Fragment or pass it as an argument everything works fine.

Zefir
  • 1
  • 1

1 Answers1

0

The list will not be updated automatically , either you need to fetch the data again then you will get the updated data or you can attach a observer to that and in viewModel use MutableLiveData to get the updates automatically.

For example in the DAO (I have used java, but try to understand the concept)

  @Query("Select * From Transactions where userId like :userId")
Flowable<List<TransactionItem>> getUserTransactions(int userId);

you need to make the query like this so that it automatically returns data whenever there is change in the Database concerned to that query.(I have used RXJava you can use RXKotlin for the same)

and in the viewModel make a variable like this:

MutableLiveData<List<TransactionItem>> transactionsList;

and the function to fetch data from database:

 public MutableLiveData<List<TransactionItem>> getTransactionsList() {
    compositeDisposable.add(transactionDataSource.getUserTransactions(userId)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<List<TransactionItem>>() {
                @Override
                public void accept(List<TransactionItem>  
              transactionItems) throws Exception {
                    transactionsList.setValue(transactionItems);
                }
            }));
    return transactionsList;
}

Feel free to ask if something is unclear.

Kamal Nayan
  • 1,635
  • 1
  • 5
  • 19
  • Thanks. I've edited my question to show that I observe the List. I'm new to Android, can you please tell me is there fundamental difference between LiveData and Flow in this case? – Zefir Apr 11 '21 at 18:02
  • Here you will get the answer, I am referring you because this question is already answered. Have a look at https://stackoverflow.com/a/59247475/13511258 – Kamal Nayan Apr 11 '21 at 18:45