I have a StateFlow
containing a simple list of strings. I want to be able to filter that list of Strings. Whenever the filter gets updated, I want to push out a new update to the StateFlow.
class ResultsViewModel(
private val api: API
) : ViewModel() {
var filter: String = ""
val results: StateFlow<List<String>> = api.resultFlow()
.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList())
}
It's easy enough to stick a map
onto api.resultFlow()
:
val results: StateFlow<List<String>> = api.resultFlow()
.map { result ->
val filtered = mutableListOf<String>()
for (r in result) {
if (r.contains(filter)) {
filtered.add(r)
}
}
filtered
}
.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList())
But how do I get the flow to actually emit an update when filter
changes? Right now, this only works with whatever the initial value of filter
is set to.
CodePudding user response:
You could have the filter update another StateFlow that is combined with the other one. By the way, there's filter
function that is easier to use than manually creating another list and iterating to get your results.
class ResultsViewModel(
private val api: API
) : ViewModel() {
private val filterFlow = MutableStateFlow("")
var filter: String
get() = filterFlow.value
set(value) {
filterFlow.value = value
}
val results: StateFlow<List<String>> =
api.resultFlow()
.combine(filterFlow) { list, filter ->
list.filter { it.contains(filter) }
}
.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList())
}