Jure Sencar
Jure Sencar

Reputation: 624

Android room: Can calling value on LiveData be used to return plain data?

Let's say I have a room DAO function getForIdLiveData(id: String) which returns LiveData<SomeClass>.

Is it save (and how is it performance-wise) to use someClassDAO.getForIdLiveData(id).value instead of making a duplicate DAO function which returns just SomeClass?

This would save a ton of boilerplate code (as the DAO functions are typically passed on through repository in MVP or MVVM) and it appears to be working so far. I just couldn't find much information of possible future complications which I (of course) want to avoid.

Example:

Can I use this:

In someDataClassDAO

    @Query("SELECT * FROM my_table WHERE my_id = :id")
    fun getForIdLiveData(id: String): LiveData<SomeDataClass>

In MyRepo interface

    getMyInfoLiveData(id: String): LiveData<SomeDataClass>

In myRepoFactory which implements custom interface MyRepo

    @WorkerThread
    override fun getMyInfoLiveData(id: String)
        = someDataClassDAO.getForIdLiveData(id)

In myViewModel class

    // Provide LiveData for ongoing UI display
    fun provideMyInfoLiveData(id: String) = myRepo.getMyInfoLiveData(id)

    // Get some parameter for different id (one time)
    fun getOneParameter(id): Long {
        val entity = myRepo.getMyInfoLiveData(id).value
        return entity.someField
    }

Instead of:

In someDataClassDAO

    @Query("SELECT * FROM my_table WHERE my_id = :id")
    fun getForIdLiveData(id: String): LiveData<SomeDataClass>

    @Query("SELECT * FROM my_table WHERE my_id = :id")
    fun getForId(id: String): SomeDataClass

In MyRepo interface

    getMyInfoLiveData(id: String): LiveData<SomeDataClass>
    getMyInfo(id: String): SomeDataClass

In MyRepoFactory which implements MyRepo

    @WorkerThread
    override fun getMyInfoLiveData(id: String)
        = someDataClassDAO.getForIdLiveData(id)

    @WorkerThread
    override fun getMyInfo(id: String)
        = someDataClassDAO.getForId(id)

In myViewModel class

    // Provide LiveData for ongoing UI display
    fun provideMyInfoLiveData(id: String) = myRepo.getMyInfoLiveData(id)

    // Get some parameter for different id (one time)
    fun getOneParameterForId(id): Long {
        val entity = myRepo.getMyInfo(id)
        return entity.someField
    }

Upvotes: 2

Views: 148

Answers (2)

EpicPandaForce
EpicPandaForce

Reputation: 81588

Is it save (and how is it performance-wise) to use someClassDAO.getForIdLiveData(id).value instead of making a duplicate DAO function which returns just SomeClass?

It has nothing to do with "performance-wise", it just flat-out wouldn't work.

LiveData<T> is evaluated asynchronously when there is an active observer.

T is evaluated synchronously and returned immediately (I/O access, blocking).

So you'd just get null and things wouldn't work at all. You do need the two methods.

I prefer to call them getForIdWithChanges instead of getForIdLiveData considering you do know it's a LiveData from the type system.

Upvotes: 2

Ridcully
Ridcully

Reputation: 23665

If you need both variants (LiveData and normal result) ypu should make 2 variants of the method in DAO. Everything else is a hack.

Upvotes: 0

Related Questions