Upgrade to Pro — share decks privately, control downloads, hide ads and more …

State Management Using Kotlin's Sealed Classes

State Management Using Kotlin's Sealed Classes

Managing states in android can be quite a task when not carefully approached.So many problems can occur due to poor state management,for example: poor failure handling, code becomes hard to read and multiple responsibilities for simple use cases. With Kotlin, we have Sealed classes to our rescue.

Sealed Classes are useful when modeling state’s within various app workflows. In this workshop we'll be looking at how to leverage the power of Kotlin Sealed Classes .The attendees will get to see what they are, how they work and how they can use sealed classes to mange states in developing android applications.

Harun Wangereka

November 16, 2019
Tweet

More Decks by Harun Wangereka

Other Decks in Programming

Transcript

  1. sealed class Result { data class Success(val data: List<String>) :

    Result() data class Failure(val exception: Throwable) : Result() }
  2. sealed class Result { data class Success(val data: List<String>) :

    Result() data class Failure(val exception: Throwable) : Result() } `else` clause not required, all the cases covered
  3. fun registerUser(fullName : String , email :String,password : String){ //

    TODO Make a register request // TODO Parse register response // TODO Save created user data // TODO proceed to dashboard screen }
  4. fun registerUser(fullName : String , email :String,password : String){ val

    response = registerRequest(fullName, email, password) if (response.isSuccessful){ saveUserDetails(response.body()) proceedToDashBoard() } }
  5. fun registerUser(fullName : String , email :String,password : String){ val

    response = registerRequest(fullName, email, password) if (response!!.isSuccessful){ saveUserDetails(response.body()) proceedToDashBoard() }else{ showError("An error occurred") } }
  6. fun registerUser(fullName : String , email :String,password : String){ try

    { val response = registerRequest(fullName, email, password) if (response!!.isSuccessful){ saveUserDetails(response.body()) proceedToDashBoard() }else{ showError("An error occurred") } }catch (error : IOException){ Log.d("Error",error.message) } }
  7. when(response.code()){ 401 -> showError("Unauthorized") 403 -> showError("Access to resource is

    forbidden") 404 -> showError("Resource not found") 500 -> showError("Internal Server error") 502 -> showError("Bad Gateway") 301 -> showError("Resource has been removed permanently") 302 -> showError("Resource moved,but has has been found ") else -> showError("All cases have not been covered!!") }
  8. !!

  9. Another sealed class Also has state sealed class RegisterResult {

    data class Success(val data : String) : RegisterResult() object InvalidData :RegisterResult() data class Error(val error : String) : RegisterResult() data class NetworkException(val error : String) : RegisterResult() sealed class HttpErrors : RegisterResult() { }
  10. sealed class HttpErrors : RegisterResult() { data class Unauthorized(val exception:

    String) : HttpErrors() data class ResourceForbidden(val exception: String) : HttpErrors() data class ResourceNotFound(val exception: String) :HttpErrors() data class InternalServerError(val exception: String) :HttpErrors() data class BadGateWay(val exception: String) : HttpErrors() data class ResourceRemoved(val exception: String) : HttpErrors() data class RemovedResourceFound(val exception: String) :HttpErrors() }
  11. fun registerUser(fullName : String , email :String,password : String) :

    RegisterResult{ return try { val response = registerRequest(fullName, email, password) if (response.isSuccessful) { if (response != null) { RegisterResult.Success(response.body()!!) }else{ RegisterResult.InvalidData } }else{ when(response.code()){ 401 -> RegisterResult.HttpErrors.Unauthorized(response.message()) 403 -> RegisterResult.HttpErrors.ResourceForbidden(response.message()) 404 -> RegisterResult.HttpErrors.ResourceNotFound(response.message()) 500 -> RegisterResult.HttpErrors.InternalServerError(response.message()) 502 -> RegisterResult.HttpErrors.BadGateWay(response.message()) 301 -> RegisterResult.HttpErrors.ResourceRemoved(response.message()) 302 -> RegisterResult.HttpErrors.RemovedResourceFound(response.message()) else -> RegisterResult.Error(response.message()) } } }catch (error : Exception){ RegisterResult.NetworkException(error.message) } }
  12. private fun handleRegisterResult(result: RegisterResult){ when(result){ is RegisterResult.Success -> { saveUserDetails(result.data)

    proceedToDashBoard() } is RegisterResult.HttpErrors.Unauthorized -> showError(result.exception) is RegisterResult.HttpErrors.ResourceForbidden -> showError(result.exception) is RegisterResult.HttpErrors.ResourceNotFound -> showError(result.exception) is RegisterResult.HttpErrors.InternalServerError -> showError(result.exception) is RegisterResult.HttpErrors.BadGateWay -> showError(result.exception) is RegisterResult.HttpErrors.RemovedResourceFound -> showError(result.exception) is RegisterResult.NetworkException -> showError(result.error) is RegisterResult.Error -> showError(result.error) } }