Home > database >  Android jetpack compose observeAsState() Property delegate must have a 'getValue(Nothing?, KPro
Android jetpack compose observeAsState() Property delegate must have a 'getValue(Nothing?, KPro

Time:09-23

I have implemented import androidx.compose.runtime.* as other users here have suggested yet still I can't use observeAsState to display any values like Text(text = weather.main.temp.toString()) inside composable element.

Composable:

@Composable
fun WeatherAppHomeScreen(weatherViewModel: WeatherViewModel) {
    val weather: Weather by weatherViewModel.myResponse.observeAsState()
    Text(text = weather.main.temp.toString())
}

Data class:

data class Weather(
    @SerializedName("base")
    val base: String,
    @SerializedName("clouds")
    val clouds: Clouds,
    @SerializedName("cod")
    val cod: Int,
    @SerializedName("coord")
    val coord: Coord,
    @SerializedName("dt")
    val dt: Int,
    @SerializedName("id")
    val id: Int,
    @SerializedName("main")
    val main: Main,
    @SerializedName("name")
    val name: String,
    @SerializedName("rain")
    val rain: Rain,
    @SerializedName("sys")
    val sys: Sys,
    @SerializedName("timezone")
    val timezone: Int,
    @SerializedName("visibility")
    val visibility: Int,
    @SerializedName("weather")
    val weather: List<WeatherX>,
    @SerializedName("wind")
    val wind: Wind
)

ViewModel class:

class WeatherViewModel : ViewModel() {

    val myResponse: MutableLiveData<Weather> = MutableLiveData()
    
    fun getWeather() {
        viewModelScope.launch {
            myResponse.value = retrofit.getWeather()
        }
    }
}

CodePudding user response:

The observeAsState() function returns an optional value. You can declare it as Weather? and replace the delegation with a simple state to provide smart cast:

val weatherState: State<Weather?> = weatherViewModel.myResponse.observeAsState()
val weather: Weather? = weatherState.value // allow smart cast
if (weather != null) {
    Text(text = weather.main.temp.toString())
}

In some cases you can specify initial value(not sure if it's applicable to your case), which will be used until live data have a value. In this case output will be non optional:

val weather: Weather by weatherViewModel.myResponse.observeAsState(Weather(...))
Text(text = weather.main.temp.toString())
  • Related