I have a database query with two input parameters. Defined in my DAO as:
@Transaction
@Query("SELECT * FROM event WHERE id = :id AND time > :time")
abstract fun getEventsFlow(id: Long, times: Long): Flow<List<Events>>
The two parameters are flows themselves. One coming from a preference (DataStore) and the other from user input (MutableStateFlow).
In addition, in the event the second parameter is 0, we want to ignore it. The way I have done this is with a second query.
@Transaction
@Query("SELECT * FROM event WHERE id = :id")
abstract fun getEventsFlow(id: Long): Flow<List<Events>>
This is what I came up with in my View Model to collect the flow and refresh it if either parameter ever changes. Everything appears to be working as expected, but I'm not confident there is not a better way.
val getEvents: Flow<List<Event>> =
id.flatMapLatest { id ->
settingsRepository.getTime.flatMapLatest { time ->
if (time == 0L) database.dao().getEventsFlow(id) else database.dao().getEventFlow(id, time) }
}
Is there a better (more efficient or cleaner code) way to do this? Specifically:
- Is there a flapMapLatest type operator that can take multiple input flows, so I can avoid two nested flatMapLatest calls?
- Does the (time == 0) conditional inside flatMapLatest which returns one of two different flows cause any concern?
- Should I combine the two database queries into a single one, and is there a good way to do so?
ids.combineTransform(times) { id, time -> getEventsFlow(id, time) }. But it handles back-pressure differently thanflatMapLatest. Instead of cancelling downstream flow (your database query) upon new upstream signal (id/time), it might instead drop upstream signals. It means that you might have more frequent updates in output, but you might not have the latest one.