https://kotlinlang.org logo
#coroutines
Title
# coroutines
s

samuel

02/19/2021, 11:09 PM
Hi, I’m experimenting with state flow to see if i can get some sort of reactive stack implementation. My idea is that i have a  class that holds the state, which only one subscriber observes, but multiple classes can update the state. This is what i have so far (in 🧵), but i have some strange behaviour. Calling 
replaceState
 works as expected with the subscriber getting the new value, however, calling 
updateState
 doesn’t. Does any one have a clue why this happens?
Copy code
sealed class State {
    object FirstState: State()
    object SecondState: State()
}

class StateHolder {
    private val _state: MutableStateFlow<State> =
            MutableStateFlow(LinkedList(listOf(State.FirstState)))

    val state: StateFlow<State> =
            _state.mapLatest{ it.peekFirst() }
                    .stateIn(GlobalScope, SharingStarted.Eagerly, State.FirstState)

    // works
    fun replaceState(newState: State) {
        _state.value = LinkedList(listOf(newState))
    }

    // Doesn't work
    fun updateState(newState: State) {
        _state.value = _state.value.apply { push(newState) }
    }
}

// Called from another class
myScope.launch {
    state.collectLatest { state ->
        Timber.e("state value $state")
    }   
}
sealed class State {
    object FirstState: State()
    object SecondState: State()
}
d

Dominaezzz

02/19/2021, 11:32 PM
StateFlow
doesn't update subscribers if the value is set to the same object.
You'll have to create a new object
s

samuel

02/19/2021, 11:38 PM
ahh! i didn’t expect the two objects to be the same given the contents have been changed, but it makes sense now, thank you 🙏
m

Michael Ferguson

02/20/2021, 12:04 AM
To be more specific,
StateFlow
uses
.equals
to compare and conflate values. So attempting to force an emission by simply copying/clone an object into a new object will fail.
It’s not like
LiveData
in that respect.
s

samuel

02/20/2021, 12:13 AM
Thats a pretty important detail to know, thank you. Feels rather unfortunate that in this case i would have to convert the old linked list to a list and create new linked list out of that. thats incorrect, can create a new object directly from the old collection
7 Views