3

I'm having some trouble understanding why the flow isn't working as expected in my app.

There is three flows in total. The first two flows represents each a single value that can be changed by the user. They are saved with multiplatform-settings and defined as follows.

fun flowA() = settings.getLongOrNullFlow(flowAKey).map { /* compute value */ }
fun flowB() = settings.getStringOrNullFlow(flowBKey).map { /* compute value */ }

The third flow is a sqldelight query that is dependent on the values from the first two flows. This flow is currently defined as follows.

fun flowC() = flowA().combine(flowB()) { (a, b) -> Pair(a, b) }
    .flapMapLatest { (a, b) ->
        queries.select(a, b).asFlow().mapToList().map { /* compute final value */ }
    }

When collecting the flow in the UI everything works as expected for the initial emit but not subsequent emits. Only changes to the first or second flows emits new values. When an entry is added to the database is nothing new emitted (that should emit from the sqldelight flow and propagate). The only way to see that change is to update any of the two first flows so the last flows runs again.

How can the flows be constructed so that the sqldelight flow emits both when it receives new values and when the two flow it depends on changes.

It might have something to do with the flatMapLatest as it only produces a new flow when the original flow changes. But I'm not sure how to return something inside the block that would also cause it to emit.

This is how the flow is ultimately collected for the UI in a ViewModel.

class ViewModel(private val dataRepository: DataRepository) : ViewModel() {
    val data =
        dataRepository.flowC().stateIn(
            scope = viewModelScope,
            started = SharingStarted.Eagerly,
            initialValue = emptyList(),
        )
}

If anything is unclear just ask. Thanks!

Isak
  • 548
  • 2
  • 5
  • 20
  • What is `mapToList()`? Can you show that code? Seems like the prime culprit to me because everything else looks fine. – Tenfour04 Jun 03 '22 at 13:47
  • It's just a method from `sqldelight` that maps the result to a list. https://github.com/cashapp/sqldelight/blob/master/extensions/coroutines-extensions/src/commonMain/kotlin/app/cash/sqldelight/coroutines/FlowExtensions.kt#L94 The value in the last map operation is a list of rows from the database. – Isak Jun 03 '22 at 13:49
  • Oh, then I'm stumped, because everything looks correct. `flatMapLatest` should be fine. The Flow inside it doesn't care about the upstream flows. Once it has its Query from them, it should keep monitoring the database for changes and emitting automatically. – Tenfour04 Jun 03 '22 at 13:56

0 Answers0