Is there any way to pass a Flow into a Room DAO Query method?

Viewed 416

I'm working on implementing Room in an android app and I have a use case where I am receiving a Flow with the current user id for functionality similar to switching which logged in Google user to view a service as. I'd like to pass that flow into a @Query annotated method in my DAO to get user widgets so that if the currently selected user changes or the list of widgets stored changes, the output Flow<List> would change as well.

Something like

WidgetRepo.kt

val widgets: Flow<List<Widget>> = widgetDAO.getWidgetsByUser(currentUserID)

WidgetDao.kt

@Query("select * from widget where userID = :userID")
fun getWidgetsByUser(userID: Flow<Int>): Flow<List<Widget>>
2 Answers

I don't think that's a good practice. I would rather do the following logic in a specific use-case, for example:

class GetWidgetsByUserUseCase(
    private val userRepo: UserRepository,
    private val widgetLocalSource: WidgetRepository
){

    suspend operator fun invoke() = userRepo.flatMapLatest { user ->
            widgetLocalSource.getWidgetsByUser(user.id)
        }

}

With this implementation every time a new user is emitted, the widgetLocalSource.getWidgetsByUser() will be triggered and the previous flows will be canceled.

See flatMapLatest for more information on the operator.

Room Database has supported Flow since before. Add this to gradle:

 // Kotlin Extensions and Coroutines support for Room - latest Room version 2.3.0
 implementation("androidx.room:room-ktx:$room_version")

See more Write observable queries with Room here.

Related