Reputation: 2661
I was able to make it work with a JSON object response but when I tried a JSON Array response I am having an error
Expected BEGIN_OBJECT but was BEGIN_ARRAY at path $
Lets say I am using this JSON Array
[
{
"id": 272846,
"date": "2021-04-04T15:26:48",
"link": "https://sample.com/crypto-that-surged-by-1250-in-2021-teams-up-with-cardano/",
"title": {
"rendered": "sample"
},
"content": {
"rendered": "sample",
"protected": false
},
"author": 52,
"jetpack_featured_media_url": "https://sample.com/wp-content/uploads/2021/01/Untitled-design-3-1.jpg"
},
{
"id": 272841,
"date": "2021-04-04T11:03:54",
"link": "https://sample.com/global-financial-services-company-btig-is-bullish-on-bitcoin-and-microstrategy/",
"title": {
"rendered": "sample"
},
"content": {
"rendered": "sample",
"protected": false
},
"author": 52,
"jetpack_featured_media_url": "https://sample.com/wp-content/uploads/2021/04/3-feb-2021-05-1024x576-1.jpg"
}
]
The generated Kotlin (Codegen) class using this plugin
class NewsItemModels : ArrayList<NewsItemModel>()
@JsonClass(generateAdapter = true)
data class NewsItemModel(
@Json(name = "author")
val author: Int,
@Json(name = "content")
val content: Content,
@Json(name = "date")
val date: String,
@Json(name = "id")
val id: Int,
@Json(name = "jetpack_featured_media_url")
val jetpackFeaturedMediaUrl: String,
@Json(name = "link")
val link: String,
@Json(name = "title")
val title: Title
)
With a service like this
@GET("posts")
fun getNewsItems(
@Query("_fields") key: String,
@Query("per_page") part: String,
@Query("categories") category: String
):
Observable<NewsItemModels>
Service interface
companion object {
fun create(baseUrl: String): EndpointServices {
val retrofit = Retrofit.Builder()
.addCallAdapterFactory(
RxJava2CallAdapterFactory.create()
)
.addConverterFactory(
MoshiConverterFactory.create()
)
.baseUrl(baseUrl)
.build()
return retrofit.create(EndpointServices::class.java)
}
}
Fetching
fetch.getNewsItems(
"author,id,title,content,date,link,jetpack_featured_media_url",
"30",
categoryId
) //Get the first channel id
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ result ->
Log.wtf("WTF", "$result")
swipeRefreshLayout.isRefreshing = false
},
{ error ->
Log.wtf("WTF", "${error.message}")
swipeRefreshLayout.isRefreshing = false
}
)
I was able to work with JSON Object response but not with JSONArray as much as possible I want only one Retrofit.Builder code. What is the missing part here?
Upvotes: 0
Views: 469
Reputation: 13321
You can either do:
@GET("posts")
fun getNewsItems(
@Query("_fields") key: String,
@Query("per_page") part: String,
@Query("categories") category: String
): Observable<List<NewsItemModel>>
or update your definition of NewsItemModels
to:
typealias NewsItemModels = List<NewsItemModel>
The error message:
Expected BEGIN_OBJECT but was BEGIN_ARRAY at path $
comes from Gson, and it's telling you that based on the way you defined the getNewsItems
it's expecting an object (you defined NewsItemModels
as a class) but it's getting an array.
In your example JSON the received payload it's an array so you need to update the return type to either inline the List
or use a typealias
.
Upvotes: 3