I have one call that return different objects name, in this case, each name is the hash of your wallet address, but I would like to treat them indifferently because all that matters is the data that is inside them, using a standard converter like Gson I am not able to do this, is there any way to do it manually?
{
"0x1234": {
"success": true,
"cache_last_updated": 1642815869695,
"total": 500
},
"0x1244445": {
"success": true,
"cache_last_updated": 1642815869695,
"total": 324
},
"0x47851":{
"success": true,
"cache_last_updated": 1642815869695,
"total": 324
}
}
My Repository:
class WalletsResumeRepository(
private val service: apiService
) {
suspend fun getAddressData(listAddress: List<String>): Flow<Result<List<DetailModel>>> =
flow {
emit(Result.success(service.getWalletResume(listAddress))
}.catch { e ->
emit(Result.failure(RuntimeException("Something went wrong ${e.cause}")))
}
}
my repository always falls into the catch scenario with an NPE, remembering that the response can have countless addresses so infinite object names, how can I treat them as generics and map only the responses as lists? or something like that?
Service.kt
suspend fun getWalletResume(@Path("address") wallet: String): WalletDetailDTO
WalletDTO
data class WalletDetailDTO(
val success: Boolean,
@SerializedName("cache_last_updated")
val cacheLastUpdated: Long?,
val totalSlp: Int?
)
As I understand your question, this is less to do with retrofit and more with JSON parsing. Because the payload structure is a bit awkward I suggest you consume it in two steps:
content
success
, cache_last_updated
and total
id
data class DetailModel(val id: String = "", val success: Boolean, val cache_last_updated: Long, val total: Int)
interface apiService {
@GET("....")
fun getWalletResume( listAddress: List<String> ): Call<Map<String, DetailModel>>
}
The result of calling apiService.getWalletResume
is Map<String, DetailModel>
which you then process in step 2.
Example
val json = """
{
"0x1234": {
"success": true,
"cache_last_updated": 1642815869695,
"total": 500
},
"0x1244445": {
"success": true,
"cache_last_updated": 1642815869695,
"total": 324
},
"0x47851": {
"success": true,
"cache_last_updated": 1642815869695,
"total": 324
}
}
""".trimIndent()
data class DetailModel(val id: String = "", val success: Boolean, val cache_last_updated: Long, val total: Int)
fun main() {
val gson = Gson()
val type: Type = object : TypeToken<Map<String, DetailModel>?>() {}.type
// step 1. simulates the retrofit call
val mapResult: Map<String, DetailModel> = gson.fromJson(json, type)
// step 2
val result = mapResult.map { entry -> entry.value.copy(id = entry.key) }
println(result)
// [DetailModel(id=0x1234, success=true, cache_last_updated=1642815869695, total=500), DetailModel(id=0x1244445, success=true, cache_last_updated=1642815869695, total=324), DetailModel(id=0x47851, success=true, cache_last_updated=1642815869695, total=324)]
}