Search code examples
androidjsonkotlinretrofit2rx-java

java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY?


I am developing new app and I have implemented retrofit call using rxjava and kotlin but I am getting following exception com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $

below my MemberActivity.kt where I have implemented network call

class MemberActivity : AppCompatActivity() {

    private var memberAdapter:MemberAdapter? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_member)

        val compositeDisposable = CompositeDisposable()
        compositeDisposable.add(
            ServiceBuilder.buildService(SpectrumInterface::class.java).getMembers()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(
                    { member -> onResponse(member) },
                    { t -> onFailure(t) })
        )

    }

    private fun onFailure(t: Throwable) {
        Toast.makeText(this, t.message, Toast.LENGTH_SHORT).show()
    }

    private fun onResponse(member: Member) {

        memberAdapter = member?.let {
            MemberAdapter()
        }

        progressBar.visibility = View.GONE
        recyclerView.apply {
            setHasFixedSize(true)

            layoutManager = LinearLayoutManager(this@MemberActivity)
            adapter = memberAdapter
        }
    }
}

below Adapter class

class MemberAdapter : RecyclerView.Adapter<MemberAdapter.MemberViewHolder>() {

    private lateinit var members: List <Member>


    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): MemberAdapter.MemberViewHolder {
      val view = LayoutInflater.from(parent.context).inflate(R.layout.member_list, parent, false)
        return MemberViewHolder(view)

    }

    override fun getItemCount(): Int {
       return members.size
    }

    override fun onBindViewHolder(holder: MemberAdapter.MemberViewHolder, position: Int) {
     return holder.bind(members[position])
    }

    class MemberViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        private val memberAge: TextView = itemView.findViewById(R.id.memberAge)
        private val memberName: TextView = itemView.findViewById(R.id.memberName)
        private val lastName: TextView = itemView.findViewById(R.id.lastName)
        private val firstName:TextView = itemView.findViewById(R.id.firstName)
        private val emailAddress:TextView = itemView.findViewById(R.id.emailAddress)
        private val phone:TextView = itemView.findViewById(R.id.phone)

        fun bind(member: Member) {

            memberAge.text = member.age.toString()
            memberName.text = member.name.toString()
            lastName.text = member.name.last
            firstName.text = member.name.first
            emailAddress.text = member.email
            phone.text = member.phone

        }
    }

}

below Member.kt data class

data class Member(
    @SerializedName("age")
    val age: Int,
    @SerializedName("email")
    val email: String,
    @SerializedName("_id")
    val id: String,
    @SerializedName("name")
    val name: Name,
    @SerializedName("phone")
    val phone: String
)

below my ServiceBuilder.kt

object ServiceBuilder {
    private val client = OkHttpClient.Builder()
        .addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
        .build()


    private val retrofit = Retrofit.Builder()
        .baseUrl("https://api.npoint.io/")
        .addConverterFactory(ScalarsConverterFactory.create())
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
        .client(client)
        .build()

    fun<T> buildService(service: Class<T>): T{
        return retrofit.create(service)
    }
}

below my Interface

interface SpectrumInterface {
  
    @GET("15c43d65bc7a989f47f1")
    fun getMembers(): Observable<Member>

}

Solution

  • Your response as arraylist but you are access as object

    so change the response like

    fun getMembers(): Observable<List<Member>>
    

    then

    private fun onResponse(member: List<Member>) 
    {// your code
    }