How do I use an enum within a kotlin data class

2.5k views Asked by At

I have this model

data class HourlyModel(
    val time: String,
    @DrawableRes val image: Int,
    val temp: Double
)

I realized that the server will provide me with weather codes which translate to the icon that will be displayed. I think if I pull the @DrawableRes into an enum, it maybe better because I have a model for Today's Weather and WeeklyWeather forecasts.

All 3 models will be using the same weather codes. I am new to Kotlin but I think if I have an enum class, I should be able to somehow use this within each model

enum class WeatherTypes (
    val weatherCode: Int,
    @DrawableRes val drawable: Int
) {
    SUNNY(0, R.drawable.sunny_t),
    RAIN(1,R.drawable.rain_t);
    
    companion object {
        fun weatherToImage(weatherCode: Int) = when(weatherCode) {
            0 -> SUNNY
            1 -> RAIN
            else -> SUNNY
        }
    }
}

Can someone help me out and tell me what I should do to my model to use this enum class to replace the @DrawableRes? if I can't then what is the best option for me?

1

There are 1 answers

3
Xid On BEST ANSWER

I'll assume you have different models for different layers. Let's say you have a data class for the data you receive from the server.

data class HourlyDto(
    val time: String,
    val weatherCode: Int,
    val temp: Double,
)

Your domain model will be something like so:

data class HourlyModel(
    val time: String,
    val weatherType: WeatherType,
    val temp: Double,
)

I've refactored your enum class:

enum class WeatherType(
    @DrawableRes val imageResId: Int,
) {
    SUNNY(R.drawable.sunny_t),
    RAIN(R.drawable.rain_t);

    companion object {
        fun from(weatherCode: Int): WeatherType {
            return WeatherType.values()[weatherCode]
        }
    }
}

Now, you can map your remote model to your domain model. Let's create an extension function for doing that( for the sake of example. You may be doing it another way )

fun HourlyDto.mapToModel(): HourlyModel {
    return HourlyModel(
        time,
        WeatherType.from(weatherCode),
        temp
    )
}

Finally, you can use you can get your drawable resource-id like so:

val hourlyWeather: HourlyModel = ...
hourlyWeather.weatherType.imageResId

Note: This answers the question of how to use the enum in your model class, but I guess to solve this specific issue you could use original model(with drawable resource-id) and then create a helper function that takes in weathercode and returns the drawable resource-id and reuse that wherever required.