Expected BEGIN_ARRAY But Was BEGIN_OBJECT At Line 1 Column 2 Path $ JSON Array Kotlin
I want to retrieve a JSON Array, How can I adjust my codebase to that. I have used the retrofit library to retrieve the data and I used the MVVM architecture. I get the error Expec
Solution 1:
The issue is, the response returns you venues
and you are expecting a List<Venue>
, so what should work for you is, create another data class that is like this:
data class Venues(
val venues: List<Venue>
)
and then inside the GET
request return Call<Venues>
Do tell if that fixes it for you :)
UPDATE
Ok, that was a bit lengthy conversation but finally here is your detailed solution, hope this resolves everything for you!
Baca Juga
- What Is The Clean Way To Check A Select Query Result's Length In Mvvm Architecture?
- How Can I Make Separate Code On Onchanged() While Observing With Livedata In Mvvm? [not Solved]
- How To Retrieve List Of Objects From Dao Via Livedata<> In View Model When There Is No Change To Trigger Onchange Method In View Model In Android
ViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
class ViewModel : ViewModel() {
private val repository = Repository()
fun getData(longLat: String, date: String): LiveData<mainResponse?> {
repository.fetch(longLat, date)
return repository.data
}
}
Repository
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
class Repository {
private val _data: MutableLiveData<mainResponse?> = MutableLiveData(null)
val data: LiveData<mainResponse?> get() = _data
fun fetch(longlat: String, date: String) {
val retrofit = Retro()
val api = retrofit.retro.create(api::class.java)
api.get(
longLat = longlat,
date = date
).enqueue(object : Callback<mainResponse>{
override fun onResponse(call: Call<mainResponse>, response: Response<mainResponse>) {
val res = response.body()
if (response.code() == 200 && res != null) {
_data.value = res
} else {
_data.value = null
}
}
override fun onFailure(call: Call<mainResponse>, t: Throwable) {
_data.value = null
}
})
}
}
MainActivity
private val viewModel by viewModels<ViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel.getData(
longLat = "40.7,-74", // sample latitude and longitude
date = "20210715" // date format is: YYYYMMDD
).observe(this, Observer {
it?.let { res ->
res.response.venues.forEach { venue ->
val name = venue.name
val location = venue.location
Log.d("name ",name)
Log.d("address ", location.address)
}
}
})
}
}
Api Interface
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Query
interface api {
@GET("v2/venues/search")
fun get(
@Query("ll") longLat: String,
@Query("client_id") id: String = Const.clientId,
@Query("client_secret") secret: String = Const.clientSecret,
@Query("v") date: String
): Call<mainResponse>
}
Model Classes
mainResponse
data class mainResponse( val response: Response )
Response
data class Response(
val venues: List<Venue>,
val confident: Boolean
)
Location
data class Location(
val address: String,
val crossStreet: String,
val lng: Double,
val lat: Double
)
Venue
data class Venue(
val id: String,
val name: String,
val location: Location
)
Const
object Const {
const val BASE_URL = "https://api.foursquare.com"
const val clientId = "" // add yours
const val clientSecret = "" // add yours
}
Retro
class Retro {
val retro = Retrofit.Builder()
.baseUrl(Const.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
Dependencies: make sure to add activity-ktx for using ViewModel in activity
def coroutines_version = "1.4.2"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:$coroutines_version"
def lifecycle_version = "2.3.1"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
def retrofit_version = "2.9.0"
implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
implementation "com.squareup.retrofit2:converter-gson:$retrofit_version"
implementation "androidx.activity:activity-ktx:1.2.3"
Post a Comment for "Expected BEGIN_ARRAY But Was BEGIN_OBJECT At Line 1 Column 2 Path $ JSON Array Kotlin"