Skip to content

Instantly share code, notes, and snippets.

@virtual-addy
Last active October 12, 2021 13:21
Show Gist options
  • Save virtual-addy/b47cea179c0fb432946976efa9bd2630 to your computer and use it in GitHub Desktop.
Save virtual-addy/b47cea179c0fb432946976efa9bd2630 to your computer and use it in GitHub Desktop.
sealed class ApiResult<out T : Any> {
data class Success<out T : Any>(val response: T) : ApiResult<T>()
data class HttpError(val code: Int?, val message: String?) : ApiResult<Nothing>()
data class GenericError(val error: Exception) : ApiResult<Nothing>()
object InProgress : ApiResult<Nothing>()
object NoInternet : ApiResult<Nothing>()
// Override for quick logging
override fun toString(): String {
return when (this) {
is Success<*> -> "Success [data=$response]"
is HttpError -> "Http Error [httpCode=$code]"
is GenericError -> "Error [error=${error.localizedMessage}]"
is NoInternet -> "No Internet"
is InProgress -> "In progress"
}
}
}
suspend fun syncVerifyOtp(
verifyRequest: VerifyRequest
): ResultWrapper<VerifyResponse> {
return requester.makeRequestToApi {
apiService.verifyPhoneNumber(verifyRequest)
}
}
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
fun CoroutineScope.launchOnIO(
block: suspend CoroutineScope.() -> Unit
) {
this.launch(Dispatchers.IO) {
block()
}
}
fun CoroutineScope.onMain(block: () -> Unit) {
this.launch (Dispatchers.Main){
block()
}
}
suspend fun <T : Any> makeRequestToApi(
call: suspend () -> T,
): ApiResult<T> {
return try {
val data = call.invoke()
ApiResult.Success(data)
} catch (throwable: Exception) {
return when (throwable) {
is HttpException -> {
ApiResult.HttpError(throwable.code(), parseErrorMessage(throwable))
}
is IOException -> ApiResult.NoInternet
else -> ApiResult.GenericError(throwable)
}
}
}
fun parseErrorMessage(httpException: HttpException): String {
val errorBody = httpException.response()?.errorBody()?.string()
return try {
val messageObject = Gson().fromJson(errorBody, JsonObject::class.java)
messageObject.get("message").asString
} catch (ex: Exception) {
""
}
}
typealias ResultWrapper<T> = ApiResult<DataResponse<T>>
data class DataResponse<T>(
@SerializedName("data")
val data: T,
@SerializedName("developer_message")
val developerMessage: String?,
@SerializedName("error")
val error: Boolean = false,
@SerializedName("message")
val message: String?,
@SerializedName("status")
val status: Int = 0
)
lifecycleScope.launchOnIO {
val verifyResult = authApi.syncVerifyOtp(verifyRequest)
// request has completed with result
reqDialog.dismiss()
when (verifyResult) {
is ApiResult.Success -> {
// switch back to main thread from IO
onMain {
completeVerification(verifyResult.response.data)
}
}
is ApiResult.HttpError -> {
// switch to main thread scope to show error message
onMain {
val errorMessage = verifyResult.errorResponse?.developerMessage
val errorDialog = buildErrorDialog(errorMessage)
errorDialog.show()
}
}
else -> {
}
}
}
fun changePIN(
phoneNumber: String,
updatePinReq: UpdatePinReq
): LiveData<ApiResult<Any>> {
return liveData(Dispatchers.IO) {
emit(ApiResult.InProgress)
emit(appRepository.changePassword(phoneNumber, updatePinReq))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment