Reputation: 37
I have problem with mapping json getting by request using Retrofit. I have dynamic 'data' object with similar nested object's.
{
"data": {
"DZ": {
"country": "Algeria",
"region": "Africa"
},
"AO": {
"country": "Angola",
"region": "Africa"
},
"BJ": {
"country": "Benin",
"region": "Africa"
},
"BW": {
"country": "Botswana",
"region": "Africa"
},
"BF": {
"country": "Burkina Faso",
"region": "Africa"
},
"BI": {
"country": "Burundi",
"region": "Africa"
},
"CV": {
"country": "Cabo Verde",
"region": "Africa"
},
"CM": {
"country": "Cameroon",
"region": "Africa"
},
"CF": {
"country": "Central African Republic (the)",
"region": "Africa"
},
"TD": {
"country": "Chad",
"region": "Africa"
}
}
}
Any suggestion how deal with it? I want to collect all object's in one list.
Upvotes: 1
Views: 1739
Reputation: 37
everyone. I solved this problem using mapping. Also I used Moshi in order to convert json to kotlin model class, Retrofit for API call and Coroutines for easy asynchronous code
Below header data class which hold map of a country
@JsonClass(generateAdapter = true)
data class MainModel(
val data : Map<String, Country>
)
Country class
@JsonClass(generateAdapter = true)
data class Country(
@Json(name = "country")
val country : String,
@Json(name = "region")
val region : String
)
My api interface
interface Api {
@GET("data/v1/countries?limit=251") suspend fun getAllCountries(): Response<MainModel>
companion object {
var api: Api? = null
fun getInstance() : Api {
if (api == null) {
val retrofit = Retrofit.Builder()
.baseUrl("https://api.first.org/")
.addConverterFactory(MoshiConverterFactory.create())
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.build()
api = retrofit.create(Api::class.java)
}
return api!!
}
}
}
function in viewmodel class where I call api request
fun getAllCountries() {
viewModelScope.launch {
try {
val response = repository.getAllCountries()
withContext(Dispatchers.Main) {
if (response.isSuccessful) {
//do your code
} else {
onError("Error : ${response.message()} ")
}
}
} catch (e: IOException) {
onError(e.message!!)
}
}
}
Here is useful links that help me understand Coroutines https://medium.com/android-beginners/mvvm-with-kotlin-coroutines-and-retrofit-example-d3f5f3b09050
https://blog.mindorks.com/using-retrofit-with-kotlin-coroutines-in-android
Upvotes: 1
Reputation: 389
You can resolve this issue by making data classes in Kotlin as follows:
data class MajorData(
val `data`: Data
)
data class Data(
val AO: AO,
val BF: BF,
val BI: BI,
val BJ: BJ,
val BW: BW,
val CF: CF,
val CM: CM,
val CV: CV,
val DZ: DZ,
val TD: TD
)
Now you will basically pass the response from the retrofit call to the MajorData
class.
Now for better clarity, you should also make data classes for all objects such as AO
,DZ
, etc.
Example: (Taking AO
into consideration)
data class AO(
val country: String,
val region: String
)
Please make the same for others as well.
Hope this helps you out. Happy Coding! :)
Upvotes: 1