Q: My MutableStateFlow Didn’t Emit I'm using this ...
# coroutines
c
Q: My MutableStateFlow Didn’t Emit I'm using this code snippet to update
messages
from two flows (using flatMapLatest)
Copy code
private val searchString = MutableStateFlow<String>("")
    private val messages = searchString.flatMapLatest {
        if (it == "") {
            getAll()
        } else {
            search(it)
        }
    }.stateIn(viewModelScope, SharingStarted.Eagerly, null)

    suspend fun requestSearch(search: String) = searchString.emit(search)
    suspend fun requestAll() = searchString.emit("")

    fun getAll(): Flow<List<Message>> = TODO()
    fun search(search: String): Flow<List<Message>> = TODO()
But when I try
emit
to update
searchString
it doesn't work. Note: The initial condition of
""
was successfully executed.
j
How do you consume
messages
?
Using
stateIn
for
messages
seems a bit strange, as messages feel more like a stream of things than a state. The consequence of using something meant for state is that if you have twice the same message, it won't trigger events in the consumers
c
collectAsState
in a composable. I've set a breakpoint inside
flatMapLatest
to see if it is getting triggered. But that break point was never hit
I need
messages
to be consumed at a composable. So I added a
stateIn
to convert it to a StateFlow, so that I can use
collectAsState
. How do you think I should do it so that the
Flow
from messages is consumed at the composable
j
So only the last message matters?
c
Only the latest List<Message> matters. getAll and search are flows from the database.
j
Oh my bad, I didn't see that
messages
was a flow of lists, not just simple messages. How can you provide
""
as initial value then? Does this code compile?
c
Oh sorry typo. It is
null
. Edited the code snippet
👌 1
j
I think
requestSearch
and
requestAll
are not supposed to use
emit()
, you should just set the value of the flow via its
value
property:
Copy code
fun requestSearch(search: String) {
    searchString.value = search
}
fun requestAll() {
    searchString.value = ""
}
c
I tried that too.
Copy code
searchString.value = ""
But this doesn't work either
🤔 1
j
Just to be sure, you're using a non-empty value to test
requestSearch
, right? Because trying to send
""
will not trigger events of the
searchString
flow if its last value was already
""
(it only triggers when the new value is not equal to the current state)
c
Yes. I did set a break point at
requestSearch
to check if search was a non empty value
This is embarrassing.
flatmapLatest
is working (but my breakpoints did not work for some reason). My current problem is not related to this anymore. It is related to
channelFlow
and me getting a
ClosedChannelException
. Will ask a different question for that.
j
Meh don't be embarassed, it happens all the time. Let's just be glad your problem is narrowed down 😉
👍 1