Skip to content

Instantly share code, notes, and snippets.

@hoc081098
Created November 28, 2022 04:17
Show Gist options
  • Save hoc081098/7d13027c2d2323e0bab067d30ad021be to your computer and use it in GitHub Desktop.
Save hoc081098/7d13027c2d2323e0bab067d30ad021be to your computer and use it in GitHub Desktop.
Consuming #Coroutines #Flows safely in #JetpackCompose πŸ“š.
// CONSUMING FLOWS SAFELY IN JETPACK COMPOSE
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.*
import androidx.lifecycle.compose.*
import androidx.lifecycle.repeatOnLifecycle
import kotlinx.collections.immutable.*
import kotlinx.coroutines.channels.*
import kotlinx.coroutines.flow.*
@Suppress("ComposableNaming")
@Composable
fun <T> Flow<T>.collectInLaunchedEffectWithLifecycle(
vararg keys: Any?,
lifecycle: Lifecycle = LocalLifecycleOwner.current.lifecycle,
minActiveState: Lifecycle.State = Lifecycle.State.STARTED,
collector: suspend (T) -> Unit
) {
val flow = this
LaunchedEffect(flow, lifecycle, minActiveState, *keys) {
lifecycle.repeatOnLifecycle(minActiveState) { flow.collect(collector) }
}
}
@Immutable data class User(val name: String, val age: Int)
@Immutable data class UsersUiState(
val users: ImmutableList<User> = persistentListOf(),
val isLoading: Boolean = true,
val error: Throwable? = null
)
sealed class UsersSingleEvent {
data class Failure(val error: Throwable) : UsersSingleEvent()
object Success : UsersSingleEvent()
}
@HiltViewModel class UsersViewModel @Inject constructor() : ViewModel() {
private val _eventChannel = Channel<UsersSingleEvent>(Channel.UNLIMITED)
val uiStateFlow: StateFlow<UsersUiState> = TODO()
val eventFlow: Flow<UsersSingleEvent> get() = _eventChannel.receiveAsFlow()
}
@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable fun UsersScreen(
modifier: Modifier = Modifier,
viewModel: UsersViewModel = hiltViewModel()
) {
viewModel.eventFlow.collectInLaunchedEffectWithLifecycle { event ->
when (event) {
is UsersSingleEvent.Failure -> TODO()
UsersSingleEvent.Success -> TODO()
}
}
// Use "androidx.lifecycle:lifecycle-runtime-compose:2.6.0-alpha03"
val uiState = viewModel.uiStateFlow.collectAsStateWithLifecycle()
// Use uiState ...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment