Issue
Is it possible to use the AsyncResult class below to prevent redefining InFlight, Error and InFlight in UserDataAppResult and CreateUserResult?
//TODO: use this to make the below classes generic?
sealed class AsyncResult{
object InFlight : AsyncResult()
data class Error(val errorMessage: String) : AsyncResult()
data class Loaded<out T>(val users: T) : AsyncResult()
}
sealed class UserDataAppResult : AppResult() {
object InFlight : UserDataAppResult()
data class Error(val errorMessage: String) : UserDataAppResult()
data class Loaded(val users: List<User>) : UserDataAppResult()
}
sealed class CreateUserResult : AppResult() {
object InFlight : CreateUserResult()
data class Error(val errorMessage: String) : CreateUserResult()
data class Loaded(val users: User) : CreateUserResult()
}
Is it possible for the above code to look like this?
sealed class AsyncResult{
class InFlight : AsyncResult()
data class Error(val errorMessage: String) : AsyncResult()
data class Loaded<out T>(val users: T) : AsyncResult()
}
sealed class UserDataAppResult : AsyncResult()
sealed class CreateUserResult : AppResult()
val activeUsers: Flowable<UserDataAppResult> = appDatabase.userDao().getActiveUsers(appSettings.currentLanguage.ordinal)
.map<UserDataAppResult> { UserDataAppResult.Loaded(it) }
.onErrorReturn { UserDataAppResult.Error(it.localizedMessage) }
.startWith(UserDataAppResult.InFlight)
.observeOn(AndroidSchedulers.mainThread())
.share()
fun createUser(): Flowable<CreateUserResult> {
val userId = UUID.randomUUID().toString()
val user = User()
user.id = userId
return appDatabase.userDao().insertAll(user)
.map <CreateUserResult> { CreateUserResult.Loaded(user) }
.onErrorReturn { CreateUserResult.Error(it.localizedMessage) }
.startWith(CreateUserResult.InFlight)
}
Currently UserDataAppResult.Error is not found which makes sense. But is it possible to reuse the AppResult sealed class hierarchy and introduce new types.
Solution
It's not possible in Kotlin. Every type you use must have an explicitly declared class somewhere. Classes are not created implicitly by the compiler even in the case when nested classes are declared in the superclass.
For your problem, I recommend you rewrite the code from combining two inheritance-based hierarchies to one of the two combining inheritance and composition, or just restructure the hierarchy in some way, for example (I suppose the exact instance of a result would be irrelevant to you in case when it's not Loaded
):
sealed class AsyncResult {
object InFlight : AsyncResult()
data class Error(val errorMessage: String) : AsyncResult()
sealed class Loaded<out T>(val result: T) : AsyncResult() {
sealed class UserDataAppResult(users: List<User>) : Loaded<List<User>>(users)
sealed class CreateUserResult(user: User) : Loaded<User>(user)
}
}
Answered By - Alexander Udalov
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.