Reputation: 1
In the DiscoverCountries
composable page, there is a button composable that updates the value of the selectedContinent
string member of the ContinentsViewModel
ViewModel() class. I am trying to use the updated string in a different composable function in a different file, but the default empty string is being maintained.
When this specific button is clicked, it passes the viewModel1.selectContinent("North America")
function to execute, changing the value of the string in the viewmodel.
class ContinentsViewModel : ViewModel() {
val selectedContinent: MutableState<String> = mutableStateOf("")
fun selectContinent(continent: String) {
selectedContinent.value = continent
Log.d("ViewModel", "Continent selected: $continent")
}
}
item(){
val pdeCard3 = Card("Some Title", "Some Location", 123)
pdeCard3.ContinentsCard(navController,
"North America",
onContinentSelected = { viewModel1.selectContinent("North America") })
}
Here is the relevant code snippet for the function definition:
@Composable
fun ContinentsCard(navController: NavHostController, continentName: String, onContinentSelected: () -> Unit) {
Row(
modifier = Modifier
.fillMaxWidth()
.height(67.dp)
.clickable{
onContinentSelected()
navController.navigate(ScreenView.ContinentsCountriesPage.route)
}
The button does correctly navigate to the ContinentsCountriesPage
, but the "North America" string in the viewmodel is not maintained, it is seen as an empty string from the destination composable.
@Composable
fun ContinentsCountriesPage(navController: NavHostController){
Log.d("ViewModelTest", "Page Opened")
val viewModel1: ContinentsViewModel = viewModel()
val selectedContinent = viewModel1.selectedContinent.value
Log.d("ViewModel", "Continent selected: $selectedContinent")
Log.d("ViewModelTest", "ContinentsCountries ViewModel: ${viewModel1.hashCode()}")
I have tried console logging the value of the selectedContinent
, the value is correctly being updated in the DiscoverCountries
code file, but an empty string in the ContinentsCountriesPage
file. I have ensured the views are under the same Navigation Host controller. When logging the hashCode of the viewmodels in each file, they are different, I'm not sure if they are supposed to be the same hashCode.
Upvotes: 0
Views: 54
Reputation: 615
In your ViewModel class, try to replace this line:
val selectedContinent: MutableState<String> = mutableStateOf("")
For this one:
var selectedContinent: MutableState<String> = mutableStateOf("")
private set
This means that your variable is only available for read
outside the ViewModel, but read & write
inside ViewModel.
Upvotes: 0
Reputation: 4256
You may consider passing the string as a navigation argument as described here: Navigate with arguments.
Or you can create an app level ViewModel
. To do so, you can pass your ComponentActivity
as a ViewModelStoreOwner
to viewModel
function. To find the parent activity you can use this function (source):
fun Context.findActivity(): ComponentActivity? = when (this) {
is ComponentActivity -> this
is ContextWrapper -> baseContext.findActivity()
else -> null
}
val appViewModel: AppViewModel = viewModel(LocalContext.current.findActivity()!!)
Upvotes: 0