Weiyi
Weiyi

Reputation: 1933

Kotlin: enums with associated values; function inside 'enum entry' gets `unresolved reference` error

I need to create a list of events with a string as name and a list of pairs as properties, some events properties are the static value, some need dynamically changed, so I create specific functions inside the enum entry to update it but complied with error unresolved reference:

Actually, what I want to implement is a list of enums with associated values, something like these articles mentioned:

Because I have more than 100 events, 95% of them are static, only several of them need to be updated during runtime, so sealed class might not suit my situation:

    enum class Event(val eventName: String, vararg eventProperties: Pair<String, String?>) {
        LOGIN_CLICKED("Login", ("View" to "button clicked")),

        LOGIN_SUCCEED("Login", ("Type" to "succeed")),

        LOGIN_ERROR("Login") {
            fun errorMessage(errorMessage: String) {
                eventProperties = listOf("ErrorType" to errorMessage)
            }
        },

        // ... some other events

        LIST_ITEM_CLICKED("LIST") {
            fun listItemName(itemName: String) {
                eventProperties = listOf("View" to itemName)
            }
        };

        var eventProperties: List<Pair<String, String?>>? = listOf(*eventProperties)


// Although this approach can fix my problem, but I don't prefer it,
// because these functions are only meaningful to specific enum item,
// I don't want them be opened to all enum items.
//
//        fun errorMessage(errorMessage: String) {
//            eventProperties = listOf("ErrorType" to errorMessage)
//        }

//        fun listItemName(itemName: String) {
//            eventProperties = listOf("View" to itemName)
//        }
    }

    fun main(args: Array<String>) {

        // unresolved reference
        println(Event.LOGIN_ERROR.eventProperties)
        Event.LOGIN_ERROR.errorMessage("error password")
        println(Event.LOGIN_ERROR.eventProperties)
    }

Upvotes: 3

Views: 1734

Answers (1)

Alexey Romanov
Alexey Romanov

Reputation: 170919

Because I have more than 100 events, 95% of them are static, only several of them need to be updated during runtime, so sealed class might not suit my situation

Why wouldn't it? If you are bothered with slightly longer declarations:

object LoginClicked : Event("Login", mapOf("View" to "button clicked")) 
\\ vs
LOGIN_CLICKED("Login", mapOf("View" to "button clicked"))

you can create a helper enum class for them:

sealed class Event(val eventName: String, val eventProperties: Map<String, String?>) {
   enum class Basic(val eventName: String, val eventProperties: Map<String, String?>) {
        LOGIN_CLICKED("Login", mapOf("View" to "button clicked")),
        LOGIN_SUCCEED("Login", mapOf("Type" to "succeed")),       
        ...
   }

   class BasicEvent(b: Basic) : Event(b.eventName, b.eventProperties)

   class LoginError(errorMessage: String) : Event("Login", mapOf("ErrorType" to errorMessage))
   ...
}

Upvotes: 2

Related Questions