Reputation: 7161
I am using MutableStateFlow in my project. When we initialise the MutableStateFlow object we need to give default value.
val topics = MutableStateFlow<List<String>>(emptyList())
when I collect this value
[null, "Hello", "world"]
I want to pass this list in adapter . So is there a way we can remove the null object before passing in adapter or Is there any better way ?
viewModel.topics.collect { topicsList ->
println(topicsList) // [null, "Hello", "world"]
adapter.submitList(topicsList)
}
Upvotes: 6
Views: 9945
Reputation: 21
You can simply ignore the first value by using drop(1)
:
viewModel.topics.drop(1).collect { topicsList ->
...
}
Upvotes: 1
Reputation: 1481
If we have given a common generic type sealed class.
Common Sealed Class
sealed class Resource<T>(val data: T? = null, val error: String? = null) {
class Loading<T> : Resource<T>()
class Success<T>(data: T) : Resource<T>(data = data)
class Error<T>(error: String) : Resource<T>(error = error)
}
In that case, we can set the initial value like this.
private val _mutableStateFlow: MutableStateFlow<Resource<List<PackageModel>>?> = MutableStateFlow(null)
PackageModel is Model/Pojo class
Upvotes: 1
Reputation: 2256
If you want to ignore initial value of StateFlow, set initial value null
or anything you want. Then you can use filter
function on flow.
For example initial value is null
launch {
val topicsState = MutableStateFlow<List<String?>?>(null)
topicsState.filterNotNull().map { topics -> topics.filterNotNull() }.onEach { topics ->
println(topics)
}.launchIn(this)
launch {
delay(1000)
topicsState.update { listOf(null, "Hello", "world") }
}
}
Output
[Hello, world]
Upvotes: 2
Reputation: 161
Since it emits a list of strings you could try to initialise the StateFlow with a null like so
val topics = MutableStateFlow<List<String>?>(null)
And when you collect you can check if the emitted value is null or not
viewModel.topics.collect { topicsList ->
topicsList?.let { safeTopics ->
adapter.submitList(safeTopics)
}
}
Upvotes: 2
Reputation: 8857
I think what you need is this:
val sampleList = listOf(null, "Hello", "world")
val topics = MutableStateFlow<List<String>>(sampleList.filer { it != null })
Upvotes: 0
Reputation: 93629
If you don't want it to have an enforced initial value, use MutableSharedFlow instead. If you give it replay = 1
, onBufferOverflow = BufferOverflow.DROP_OLDEST
, and distinctUntilChanged()
, it's basically the same thing as a MutableStateFlow without the enforced value
. And if onBufferOverflow
is not BufferOverflow.SUSPEND
, tryEmit
will always succeed so you can use tryEmit()
instead of value =
.
private val _topics = MutableSharedFlow<List<String>>(
replay = 1,
onBufferOverflow = BufferOverflow.DROP_OLDEST
)
val topics: Flow<List<String>> = _topics.distinctUntilChanged()
// emitting to the shared flow:
_topics.tryEmit(newValue)
Upvotes: 5