2

Can I create a StateFlow from a Flow so that I can get the .value of it? Is there a way to do it without using .collect?

Something like

val myStateFlow = StateFlow<MyDataType>(this.existingFlow)

So that later, when someone clicks a button, I can say what the last value of the flow is?

fun handleButton() {
  val lastValue = myStateFlow.value
  print(lastValue)
}

I would prefer not using collect, since I dont want the flow to flow until someone else decides to collect it.

SpecialEd
  • 473
  • 5
  • 17
  • [stateIn](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/state-in.html) – IR42 Dec 16 '21 at 08:15

1 Answers1

0

There is a built-in function called stateIn.

Is there a way to do it without using .collect? I would prefer not using collect, since I dont want the flow to flow until someone else decides to collect it.

If you use the non-suspending overload of stateIn, the flow collection doesn't have to start right away, but you have to provide an initial value for the state (because this call cannot wait for the first value of the flow if it doesn't suspend).

In that case, you can play with the started argument to make the actual collection lazy, but note that accessing myStateFlow.value won't trigger the collection of the flow and will just return the initial value over and over. Only terminal flow operators (like collect) on the StateFlow will actually trigger the underlying flow collection, which is probably not what you want (but maybe it is!).

Note that you have to have a coroutine running to get the values from the initial flow and set the state accordingly if you want to access values via myStateFlow.value. This is actually what stateIn does by default: it starts a coroutine that collects the flow to set the StateFlow's value - so it technically uses collect.

Joffrey
  • 32,348
  • 6
  • 68
  • 100