Skip to content

Instantly share code, notes, and snippets.

@Aldikitta
Last active August 7, 2023 09:00
Show Gist options
  • Save Aldikitta/8f28b94693562b83ca755d7c02bfaa73 to your computer and use it in GitHub Desktop.
Save Aldikitta/8f28b94693562b83ca755d7c02bfaa73 to your computer and use it in GitHub Desktop.
The way using BaseResponse with mapper
// BaseResponseDto
data class KreditPlusBaseResponseDto<DATA>(
@SerializedName("code")
val code: Int? = 0,
@SerializedName("data")
val data: DATA?,
@SerializedName("errors")
val errors: HashMap<String, String>? = hashMapOf(),
@SerializedName("status")
@Expose
val status: String?,
@SerializedName("message")
@Expose
val message: String?,
@SerializedName("validation")
@Expose
val validation: HashMap<String, String>? = hashMapOf(),
@SerializedName("total_page")
val totalPage: Int? = 0,
@SerializedName("total_data")
val totalData: Int? = 0,
@SerializedName("paginator")
val paginator: BasePagingResponse? = null,
@SerializedName("log_token")
val logToken: String? = null
)
// BaseResponseModel
data class KreditPlusBaseResponseModel<DATA>(
val code: Int? = 0,
val data: DATA?,
val errors: HashMap<String, String>? = hashMapOf(),
val status: String?,
val message: String?,
val validation: HashMap<String, String>? = hashMapOf(),
val totalPage: Int? = 0,
val totalData: Int? = 0,
val paginator: BasePagingResponse? = null,
val logToken: String? = null
)
// Mapper
fun <T, R> KreditPlusBaseResponseDto<T>.toKreditPlusBaseResponseModel(dataMapper: ((T) -> R)?): KreditPlusBaseResponseModel<R> {
return KreditPlusBaseResponseModel(
code = this.code,
data = this.data?.let { dataMapper?.invoke(it) },
errors = this.errors,
status = this.status,
message = this.message,
validation = this.validation,
totalPage = this.totalPage,
totalData = this.totalData,
paginator = this.paginator,
logToken = this.logToken
)
}
// API SERVICE
@GET("agent-prospect")
suspend fun getListAgentProspect(
@Header("Authorization") token: String,
@QueryMap body: MutableMap<String, Any>,
): KreditPlusBaseResponseDto<List<ListProspectAgentResponseDto.ListProspectAgentDataResponse>>
@GET("agent-prospect/{id}")
suspend fun getDetailAgentProspect(
@Header("Authorization") token: String,
@Path(value = "id", encoded = true) id: Int
): KreditPlusBaseResponseDto<DetailProspectAgentResponseDto.DetailProspectAgentDataResponse>
@POST("agent-prospect")
suspend fun createAgentProspect(
@Header("Authorization") token: String,
@Body body: CreateProspectAgentRequestDto.CreateProspectAgentRequest,
): KreditPlusBaseResponseDto<Nothing>
// DATA SOURCE
suspend fun getListAgentProspect(
token: String,
body: ListProspectAgentRequestDto.ListProspectAgentRequest
): KreditPlusBaseResponseDto<List<ListProspectAgentResponseDto.ListProspectAgentDataResponse>> {
return agentActivityService.getListAgentProspect(
token = token,
body = convertDataClassToMap(body)
)
}
fun getDetailAgentProspect(
token: String,
id: Int
): Flow<KreditPlusBaseResponseDto<DetailProspectAgentResponseDto.DetailProspectAgentDataResponse>> {
return flow {
while (true) {
val detailAgentProspect = agentActivityService.getDetailAgentProspect(
token = token,
id = id
)
emit(detailAgentProspect)
delay(Constant.DELAY_5_MINUTES)
}
}
}
suspend fun createAgentProspect(
token: String,
body: CreateProspectAgentRequestDto.CreateProspectAgentRequest
): KreditPlusBaseResponseDto<Nothing> {
return agentActivityService.createAgentProspect(
token = token,
body = body
)
}
// REPOSITORY
override fun getListAgentProspect(body: ListProspectAgentRequestModel.ListProspectAgentRequest):
Flow<PagingData<ListProspectAgentResponseModel.ListProspectAgentDataResponse>> {
val requestModel = body.toListProspectAgentRequestDto()
return Pager(
config = PagingConfig(
pageSize = 20,
prefetchDistance = 20
),
pagingSourceFactory = {
ListAgentProspectPagingSource(
token = "Bearer ${getAccountInfo().token}",
listProspectAgentRequestDto = requestModel,
agentVisitDataSource = agentVisitDataSource
)
}
).flow.map { pagingData ->
pagingData.map { data ->
data.toListProspectAgentDataResponseModel()
}
}
}
override fun getDetailAgentProspect(id: Int):
Flow<KreditPlusResponse<KreditPlusBaseResponseModel<DetailProspectAgentResponseModel.DetailProspectAgentDataResponse>>> {
return agentVisitDataSource.getDetailAgentProspect(
token = "Bearer ${getAccountInfo().token}",
id = id
).map {
it.toKreditPlusBaseResponseModel { data ->
data.toDetailProspectAgentDataResponseModel()
}
}.asFlowKreditPlusResponse()
}
override suspend fun createAgentProspect(body: CreateProspectAgentRequestModel.CreateProspectAgentRequest):
KreditPlusResponse<KreditPlusBaseResponseModel<Nothing>> {
return asSuspendKreditPlusResponse {
val requestDto = body.toCreateProspectAgentRequestDto()
val responseDto = agentVisitDataSource.createAgentProspect(
token = "Bearer ${getAccountInfo().token}",
body = requestDto
)
responseDto.toKreditPlusBaseResponseModel{
it
}
}
}
// plus notes, how to handle response validation
private fun createAgentProspectUiState() {
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.createProspectAgentUiState.collectLatest {
when (it) {
is CreateProspectAgentUiState.Loading -> {
loadingDialog.show()
successDialog.dismiss()
failedDialog.dismiss()
}
is CreateProspectAgentUiState.Success -> {
successDialog.show()
failedDialog.dismiss()
loadingDialog.dismiss()
}
is CreateProspectAgentUiState.Error -> {
failedDialog.show()
loadingDialog.dismiss()
successDialog.dismiss()
viewModel.errorEventFlow.collectLatest { showError ->
when (showError) {
is ShowErrorMessageUiEvent.ShowErrorMessage -> {
val validation =
asResponseErrorResponse(responseBodyError = showError.responseBodyError)
validation.forEach { (field, message) ->
when (field) {
"MobilePhone" -> {
binding.txtTilAgentPhone.setErrors(
errorMessage = message,
isFocusable = true,
scrollView = binding.nsvAgentVisiting
)
}
"AgentName" -> {
binding.txtTilChooseAgentName.setErrors(
errorMessage = message,
isFocusable = true,
scrollView = binding.nsvAgentVisiting
)
}
}
}
}
}
}
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment