Skip to content Skip to sidebar Skip to footer

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!

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"