Search code examples
androidkotlinandroid-roomandroid-livedataandroid-viewmodel

is this the correct way of LiveData usage?


I am currently applying Room + ViewModel + LiveData to my project. In my app, there is "obviously" observe data that is needed, but not all.

The code below is example code for category data. In my situation, category data does not change and always maintains the same value state (13 categories and content does not change). Categories are data that is loaded from the Database through the CategoryItemDao class.

Does category data need to be wrapped with livedata? Or is there a reason enough to use LiveData in addition to its observerable feature?

I've read the guide to LiveData several times, but I do not understand the exact concept.

CategoryItemDao

@Dao
interface CategoryItemDao {
    @Query("SELECT * FROM CategoryItem")
    fun getAllCategoryItems(): LiveData<MutableList<CategoryItem>>
}

CategoryRepository

class CategoryRepository(application: Application) {
    private val categoryItemDao: CategoryItemDao
    private val allCategories: LiveData<MutableList<CategoryItem>>

    init {
        val db = AppDatabase.getDatabase(application)
        categoryItemDao = db.categoryItemDao()
        allCategories = categoryItemDao.getAllCategoryItems()
    }

    fun getAllCategories() = allCategories
}

CategoryViewModel

class CategoryViewModel(application: Application) : AndroidViewModel(application) {
    private val repository = CategoryRepository(application)
    private val allCategories: LiveData<MutableList<CategoryItem>>

    init {
        allCategories = repository.getAllCategories()
    }

    fun getAllCategories() = allCategories
}

Solution

  • This is fine, but you can make a few changes:

    1. Change LiveData<MutableList<CategoryItem>> to LiveData<List<CategoryItem>>. Don't use a MutableList unless you really have to. In your case, List would work fine.

    2. In your CategoryRepository instead of fetching in init, do it during the getAllCategories() call. So change your code like this: fun getAllCategories() = categoryItemDao.getAllCategoryItems()

    3. Similarly do the same in CategoryViewModel as well. Change you code to: fun getAllCategories() = repository.getAllCategories()

    A common misconception is to use LiveData only when the data changes. But that's not true. Your 13 categories may not change, but that's in a database. So if you were to accomplish this without a LiveData you have to query the DB and populate the view in the main thread, or you need to wrap this around in a background thread. But if you do this via LiveData, you get the Asynchronous Reactive way of coding for free. Whenever possible, try to make your view observe a LiveData.