How do I use Sandwich if the json is not a standard?
StrikeZXA opened this issue · 8 comments
How do I use Sandwich if the json is not a standard?
The response json is ....
success
{"code":0,"msg":"success", "data": {}}
fail
{"code":-1,"msg":"fail"}
Hi, could you let me know what kind of serialization library do you use? e.g., Gson, Moshi
Gson or Moshi ,I can use them all
I think this issue is related to the usage of Gson
or Moshi
.
Because converting json to object is their works.
That way I can't request in Sandwich like Pokedex App.
In a sense,I'm going to have more trouble using Sandwich.
I don't want to every time in the response. SuspendOnSuccess conversion operation.
Does Sandwich support directly returning the data field?
Now MyApp request like this
`viewModelScope.launch {
val result = appDataManager.requestVerifyCode(itac, receiveTarget)
if (result is Result.Success) {
} else if (result is Result.Error) {
}
}`
suspend fun requestVerifyCode(itac: String, receiveTarget: String): Result<VerifyCodeEntity> { return safeApiCall( call = { executeResponse(apiService.requestVerifyCode(itac,receiveTarget)) }, errorMessage = "Network Error" ) }
`
data class LazyEntity(val code: Int, val msg: String, val data: T)
suspend fun safeApiCall(call: suspend () -> Result, errorMessage: String): Result {
return try {
call()
} catch (e: Exception) {
// An exception was thrown when calling the API so we're converting this to an IOException
Logger.i("Exception = ${e.message}")
Result.Error(IOException(errorMessage, e))
}
}
suspend fun executeResponse(
response: LazyEntity,
successBlock: (suspend CoroutineScope.() -> Unit)? = null,
errorBlock: (suspend CoroutineScope.() -> Unit)? = null
): Result {
return coroutineScope {
if (response.code == 0) {
errorBlock?.let { it() }
Logger.i("Exception = ${response.msg}")
Result.Error(IOException(response.msg))
} else {
successBlock?.let { it() }
Result.Success(response.data)
}
}
}`
@Headers("Content-Type: application/json") @POST("db-api/general/sms/verify_code") suspend fun requestVerifyCode( @Field("itac") type: String, @Field("receiveTarget") receiveTarget: String, ): LazyEntity<VerifyCodeEntity>
`sealed class Result {
data class Success<out T>(val data: T) : Result<T>()
data class Error(val exception: Exception,val code:Int = 404) : Result<Nothing>()
override fun toString(): String {
return when (this) {
is Success<*> -> "Success[data=$data]"
is Error -> "Error[exception=$exception]"
}
}
}`
So I think it's going to be more troublesome to use Sandwich in my app
Hi, sorry I don't understand what you want to resolve.
As I understand, you can handle the response based on its type like the below?
val response = disneyService.fetchDisneyPosterList()
when (response) {
is ApiResponse.Success -> // do something
is ApiRespnse.Error.Failure -> //
is ApiResponse.Error.Exception -> //
}
Also, you can use like the below using if statement.
val response = disneyService.fetchDisneyPosterList()
if (response is ApiResponse.Success) {
// do something
}
hello @skydoves, i had a case like this. the endpoint return the json with template like @dempsey. my problem is when I created the base class for the response it's working. but when I'm trying to use runAndRetry extension, it's show the warning :
Type mismatch. Required: Any Found: BaseResponse<TokenResponseModel>?
but when i change the body without the BaseResponse model, the 'runAndRetry ' method working well without the warning show up.
how do i solve this?
this is my base response model class
@Keep @Serializable data class BaseResponse<T>( @SerializedName("error") val error: ErrorModel? = null, @SerializedName("success") val success: Boolean?, @SerializedName("data") val data: T? = null )
BTW, this dependency is aweseom! it's really helped me with the development process that I was doing