Reputation: 480
I have to load reviews based on storeURL and the SKUs of the products. For SKUs I make a network call and get the products in a MutableFlow. The storeURL is in a compositionLocal. Now, how do I pass this storeURL from composition local to the viewModel.
This is the function for loading reviews in viewModel
fun loadReviews(products: List<Storefront.Product>?, storeUrl: String) {
viewModelScope.launch(Dispatchers.IO) {
when (val result = getReviews(products, storeUrl)) {
is Resource.Loading -> Unit
is Resource.Success -> {
val data = result.data
data.whatIfNotNull {
reviews.value = it
}
}
is Resource.Error -> Unit
}
}
}
This is how I want to do it in the init block
init {
viewModelScope.launch {
productsList.collectLatest { products ->
loadReviews(products, [HOW TO GET STORE URL FROM COMPOSITION LOCAL HERE])
}
}
}
Upvotes: 3
Views: 1592
Reputation: 1700
There are multiple ways. For starters you can avoid launching the productsList
inside the init and instead have a function that launches it which gets called from a LaunchedEffect.
@Composable fun ProductScreen(viewModel: ProductViewModel) {
val compositionStuff = Whatever.current
LaunchedEffect(Unit) { viewModel.loadProducts(compositionStuff) }
}
Alternatively you can include a SavedStateHandle
as parameter in your ViewModel and when instantiating the ViewModel (using Hilt) make sure it's properly scoped so navigation parameters are passed to it.
composable("/products/{storeUrl}") {
val vm = hiltViewModel<ProductViewModel>(it)
ProductScreen(vm)
}
@HiltViewModel
class ProductViewModel @Inject constructor(
savedStateHandle: SavedStateHandle,
) : ViewModel () {
private val storeUrl: String = savedStateHandle["storeUrl"]!!
init { loadProducts(products, storeUrl) }
}
Upvotes: 1