Last active
July 23, 2023 23:46
-
-
Save marcellogalhardo/2a1ec56b7d00ba9af1ec9fd3583d53dc to your computer and use it in GitHub Desktop.
A helper function to let you expose a MutableStateFlow from a SavedStateHandle.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Returns a [StateFlow] that access data associated with the given key. | |
* | |
* @param scope The scope used to synchronize the [StateFlow] and [SavedStateHandle] | |
* @param key The identifier for the value | |
* @param initialValue If no value exists with the given [key], a new one is created | |
* with the given [initialValue]. | |
* | |
* @see SavedStateHandle.getLiveData | |
*/ | |
fun <T> SavedStateHandle.getStateFlow( | |
scope: CoroutineScope, | |
key: String, | |
initialValue: T | |
): MutableStateFlow<T> { | |
val liveData = getLiveData(key, initialValue) | |
val stateFlow = MutableStateFlow(initialValue) | |
// Synchronize the LiveData with the StateFlow | |
val observer = Observer<T> { value -> | |
if (stateFlow.value != value) { | |
stateFlow.value = value | |
} | |
} | |
liveData.observeForever(observer) | |
stateFlow.onCompletion { | |
// Stop observing the LiveData if the StateFlow completes | |
withContext(Dispatchers.Main.immediate) { | |
liveData.removeObserver(observer) | |
} | |
}.onEach { value -> | |
// Synchronize the StateFlow with the LiveData | |
withContext(Dispatchers.Main.immediate) { | |
if (liveData.value != value) { | |
liveData.value = value | |
} | |
} | |
}.launchIn(scope) | |
return stateFlow | |
} |
Hey @StylianosGakis.
Yes, based in the documentation you posted you can remove the if-else
.
About a library, I'm not familiar with any but I guess it is simpler to write a custom function in each project for that - I expect Google to add flow support to SavedStateHandle
at some point in the future.
Great helper function, thanks!
Would it be an idea to make T : Parcelable
?
Hey @PatrickKuijpers, that would work but keep in mind you would block those functions to be used with primitives and other supported types (such as lists), I think. That isn't a problem per see, so go ahead if these are the only types you need in your project.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
As per the documentation inside kotlinx.coroutines.flow.MutableStateFlow.value:
"Setting a value that is [equal][Any.equals] to the previous one does nothing."
Doesn't that mean that this is redundant?
and can be replaced with:
And with that said, are you aware if any library maintains this function? It's kind of hard to share and have people to use this as a gist.