Saman Sattari
Saman Sattari

Reputation: 3578

Passing Data Class Properties as Parameters in Function without Redundancy in Kotlin

I have a data class representing user settings:

@Serializable
data class UpdateSettingsRequest(
    val isNotificationsOn: Boolean?,
    val isDarkMode: Boolean?,
    val language: String?,
    val isAnimationsEnabled: Boolean?,
)

And a repository function to update these settings:

class SettingsRepository {
    fun updateSettings(request: UpdateSettingsRequest) {
        makeNetworkRequest(request)
    }

    private fun makeNetworkRequest(request: UpdateSettingsRequest) {
        TODO("make network request to update settings. request = $request")
    }
}

Currently, I use the repository like this:

fun main() {
    val repo = getSettingsRepository()
    repo.updateSettings(UpdateSettingsRequest(isNotificationsOn = false))
    // In null cases it will ignore updating those fields.
}

However, I want to avoid creating UpdateSettingsRequest instances outside the repository, so I changed updateSettings to accept individual parameters:

class SettingsRepository {
    fun updateSettings(
        isNotificationsOn: Boolean? = null,
        isDarkMode: Boolean? = null,
        language: String? = null,
        isAnimationsEnabled: Boolean? = null,
    ) {
        val request = UpdateSettingsRequest(
            isNotificationsOn = isNotificationsOn,
            isDarkMode = isDarkMode,
            language = language,
            isAnimationsEnabled = isAnimationsEnabled,
        )
        makeNetworkRequest(request)
    }

    private fun makeNetworkRequest(request: UpdateSettingsRequest) {
        TODO("make network request to update settings. request = $request")
    }
}

This approach allows me to call the function more cleanly:

fun main() {
    val repo = getSettingsRepository()
    repo.updateSettings(isNotificationsOn = false)
}

However, if I add new properties to UpdateSettingsRequest, I'll need to update updateSettings each time, which is error-prone.

Question: Is there a more maintainable approach in Kotlin that would allow me to handle this without duplicating properties in updateSettings?

Upvotes: 0

Views: 60

Answers (1)

Nongthonbam Tonthoi
Nongthonbam Tonthoi

Reputation: 12963

Other have posted their opinions in the comments. One solution would be to make the data class parameters as var

Now inside the SettingsRepository you can do:

companion object {
    inline fun buildRequest(request: UpdateSettingsRequest.() -> Unit): UpdateSettingsRequest {
        return UpdateSettingsRequest().apply(request)
    }
}

After that you should be be able to call:

repo.updateSettings(SettingsRepository.buildRequest {
    isNotificationsOn = false
    language = "en-us"
})

Note that make the parameter var may not be desirable in some cases.

Upvotes: 0

Related Questions