Использование карты в Stateflow Котлина

С LiveData внутри Viewmodel мы используем switchMap или Transformations.map, как это

      val recipesList = cuisineType.switchMap { repository.getDisplayRecipes(it.cuisineType).asLiveData() }

Как лучше всего сделать это с помощью StateFlow? Я знаю, что мы можем просто использовать карту, как показано ниже, однако это вернет мне Flow <Flow <List <Recipe >>>, что не кажется правильным

      val recipeListFlow = cuisineTypeStateFlow.map {
    repository.getDisplayRecipes(it.cuisineType)
}

2 ответа

Официального способа сделать это до сих пор нет (пока), но есть разумная рекомендация https://github.com/Kotlin/kotlinx.coroutines/issues/2631#issuecomment-870565860 :

      /**
 * Does not produce the same value in a raw, so respect "distinct until changed emissions"
 * */
class DerivedStateFlow<T>(
    private val getValue: () -> T,
    private val flow: Flow<T>
) : StateFlow<T> {

    override val replayCache: List<T>
        get () = listOf(value)

    override val value: T
        get () = getValue()

    @InternalCoroutinesApi
    override suspend fun collect(collector: FlowCollector<T>): Nothing {
        coroutineScope { flow.distinctUntilChanged().stateIn(this).collect(collector) }
    }
}

fun <T1, R> StateFlow<T1>.mapState(transform: (a: T1) -> R): StateFlow<R> {
    return DerivedStateFlow(
        getValue = { transform(this.value) },
        flow = this.map { a -> transform(a) }
    )
}

fun <T1, T2, R> combineStates(flow: StateFlow<T1>, flow2: StateFlow<T2>, transform: (a: T1, b: T2) -> R): StateFlow<R> {
    return DerivedStateFlow(
        getValue = { transform(flow.value, flow2.value) },
        flow = combine(flow, flow2) { a, b -> transform(a, b) }
    )
}

// and so on

Должно быть

      val recipeListFlow = cuisineTypeStateFlow.flatMapLatest {
    repository.getDisplayRecipes(it.cuisineType)
}
Другие вопросы по тегам